如果在service层的方法上同时使用事务和同步锁无法保证数据同步
@Service
public class Service{
@Transactional(readOnly = false)
public void synchronized update() {
............
}
}
*上面这个例子无法保证数据的一致性
由于spring的AOP的特性,会在update方法之前开启事务,之后再加锁,当锁住的代码执行完成后,在提交事务。
因此synchronized代码块执行是在事务之内执行的,可以推断在代码块执行完时,事务还未提交,因此其它线程进入synchronized代码块后,读取的数据库数据不是最新的。
为了解决上面的并发同步问题,可以通过synchronized方法调用update()方法,在还没有开事务之前就加同步锁,那么就可以保证线程同步。
1、原实现同步方法
同步方法或者同步方法块都不能达到同步的作用。
@Service
public class Service{
@Transactional(readOnly = false,rollbackFor = SQLException.class)
public synchronized void synMethodOne() throws SQLException{
............
}
}
@Service
public class Service{
@Transactional(readOnly = false,rollbackFor = SQLException.class)
public void synMethodTwo() throws SQLException{
synchronized(this){
............
}
}
}
2、修改后的方法
@Service
public class noTransService {
@Autowired
SynchronizedService synchronizedService;
public synchronized void synMethod() throws SQLException{
synchronizedService.synMethodTwo();
}
}
@Service
public class SynchronizedService{
@Transactional(readOnly = false,rollbackFor = SQLException.class)
public void synMethodTwo() throws SQLException{
............
}
}