当线程A将level设置为99时,此时锁已经释放了,但是事务还没提交!!线程B此时可以获取到锁并进行查询,查询出来的level还是线程A修改之前的100,所以出现了并发问题。
解决方案
1、@Transactional单独一个方法
private Lock lock = new ReentrantLock(); @Transactional public void test1() { // 简单的select + update 模拟业务场景 Model model = mapper.choseOne("99"); // 实现 level -- 操作 Model updater = new Model(); updater.setId("99"); updater.setLevel(model.getLevel() - 1); mapper.updateOne(updater); } @Autowired @Lazy private CommonService commonService; public void test() { try { // 加锁 lock.lock(); // 自己注入自己,以使用到其代理类 commonService.test1(); } finally { lock.unlock(); // 解锁 } }
2、使用编程式事务
// service代码 private Lock lock = new ReentrantLock(); @Autowired private PlatformTransactionManager transactionManager; public void test() { try { //加锁 lock.lock(); // 编程式事务 TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); // 简单的select + update 模拟业务场景 Model model = mapper.choseOne("99"); // 实现 level -- 操作 Model updater = new Model(); updater.setId("99"); updater.setLevel(model.getLevel() - 1); mapper.updateOne(updater); // 在锁中提交 transactionManager.commit(status); } finally { lock.unlock(); // 解锁 } }
标签:线程,lock,Transactional,99,updater,new,失效,Model From: https://www.cnblogs.com/jiutang001/p/18309834