@Transactional和@Synchronized的冲突
场景
方法是先进行检查,然后新增,添加了事务注解,为了保证检查(要求业务上唯一),添加了@Synchronized注解
想法很简单,事务注解保证方法原子性,锁注解控制并发,实际结果不符合预期
结论
上述save方法,是新增一个apple,要求size和color唯一
通过编译后的class文件,可以看出,事务在锁之前(事务是切面),锁注解实际是方法内的代码块,实际效果是并发请求都开启事务,第一个请求占用锁,开始业务处理,后续请求开启事务,被锁阻塞,等到占用锁进行业务处理时,采取默认的RR隔离级别,读取快照,发现可以新增,实际另外一个事务已经新增并提交了,但是没用
如何解决?
- 缩小事务范围,改为代码块事物而非注解,较为麻烦
- 移除事务注解,默认新增操作是原子性,可以保证
- 修改隔离级别为RC
ps:syn语句块结束,到事务提交,有延迟,所以获取锁要睡眠一个很短时间(不睡眠的流程可能是:请求1开事务-占用锁-处理-释放锁,请求2开事务-占用锁-处理,请求1提交完成。请求2处理即使是RC也得请求1的事务提交)