如果在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{ ............ } }