面试问题 Synchronized和@Transactional
开发时发现,@Transactional作用在方法上时,并发高的情况下,synchronized会失效。
synchronized锁:锁的是对象、方法或代码块。
@Transactional(rollbackFor=Exception.class)
public synchronized String demo(String req)throws Exception {
System.out.println("demo.......");
}
这种情况下锁可能会失效。因为synchronized 锁的是这个方法,@Transactional的事物是Spring的AOP开启的。进入这个方法前,AOP会先开启事物,然后进入方法,此时会加锁,当方法结束后,锁释放,然后才会提交事物。如果在释放锁和提交事物之间有其他线程请求,然后该线程继续加锁。。。,这种情况会导致程序不安全。所以应该在开启事物前加锁。
以下 可以保证数据的安全性,先加锁,然后在开启事物,可以保证安全性。
//创建加锁对象
final Object lock = new Object();
public String suo(String req)throws Exception {
//加锁
synchronized (lock){
//通过代理方式请求加事物的方法
return ((demo方法所在的类名) AopContext.currentProxy()).demo(String req);
}
}
@Transactional(rollbackFor=Exception.class)
public String demo(String req)throws Exception {
System.out.println("demo.......");
}
附图: