在使用@Transactional
注解的方法内部使用synchronized
,在方法执行完毕后锁就会被释放,而此时事务可能还没有被提交,此时若有其他线程对数据进行修改会出现并发安全问题。
若将锁加在函数调用的地方,将整个方法进行加锁。这样当方法执行完毕且事务也提交完毕之后锁才会被释放。
public int A(){
synchronized(){
return B();
}
}
@Transactional
public int B(){
return 1;
}
代码如上所示,因为在添加注解后Spring生成了动态代理对象,用生成的代理对象做事务处理,而这种调用方式调用的是原始对象,会导致事务失效。
解决方式
使用AopContext.currentProxy()
方法获取当前对象的代理对象
- 引入依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
</dependency>
- 启动类添加注解
@EnableAspectJAutoProxy(exposeProxy = true)
暴露代理对象
- 获取对象
public class Test(){
public int b(){
synchronized(){
//返回对象为Object,强制转换为相应的对像,注意类为Test,B只是Test类中的一个方法
Test proxy = (Test)AopContect.currentProxy();
return proxy.b();
}
}
@Transactional
public int b(){
return 1;
}
}