在我们日常的开发中,经常会接触到事务和锁,
当同时用到这二者的时候,你知道里面的坑吗?
比如,某个service
里的下面这段伪代码有问题吗?
示例代码:
@Transactional(rollbackFor = Exception.class)
public Boolean test() {
String lock = "id";
synchronized (lock.intern()) {
// 业务代码
}
// 剩余逻辑
return true;
}
很显然是有问题,因为MySQL
的默认隔离级别是可重复读,
因此在该事务提交前其他事务并不能获取到该事务对数据操作后的结果,
那么在第一个事务的synchronized
块执行完之后且事务提交之前,
其他事务在执行synchronized
块中的代码时使用的仍然是老数据,
从这方面来说其实就相当于没有锁住,也就是锁失效。
那么怎么改呢?示例代码如下:
public Boolean test() {
String lock = "id";
PostService postService = (PostService) AopContext.currentProxy();
synchronized (lock.intern()) {
return postService.innerTest();
}
return true;
}
@Transactional(rollbackFor = Exception.class)
public Boolean innerTest() {
// 业务逻辑
return true;
}
上面的代码中我们没有直接调用innerTest
方法而是通过AopContext
获取的对象调用,
你知道为什么吗?欢迎投票并在评论区讨论。
完整代码片段来源于代码小抄,欢迎点击进入小程序阅读!
在线访问:https://www.codecopy.cn/post/gzshnr