在我们日常的开发中,经常会接触到事务和锁,
当同时用到这二者的时候,你知道里面的坑吗?
比如,某个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
更多优质代码欢迎进入小程序查看!
往期推荐
今日代码 PK | 使用 try-with-resources 关闭资源
今日代码 PK | 避免循环查库
今日代码 PK | 使用 Optional 判空
今日代码 PK | Java 使用正则表达式