# 一、在service层事务中使用锁(失效) ```java //伪代码 @Transactional public sync Object test(){ xxx() } ``` 上述代码执行过程: 1. spring AOP 生成代理对象,开启事务 2. 线程1获得锁 3. 线程1执行xxx方法 4. 线程1释放锁 5. 事务提交 问题点:线程1释放锁之后,事务提交之前。由线程2获取锁执行,此时线程2查到的数据是脏数据,因此出现脏写。 ## 解决: ### 1. 将加锁过程上移至controller层 原理是将事务包在锁内 ```java private final Lock lock = new ReentrantLock(false); public ServiceResult save(@RequestBody CreditRecordsParam params) { try { if (lock.tryLock(5, TimeUnit.SECONDS)) { return creditRecordsService.save(params); } else { return ServiceResult.fail("锁获取失败,请重新提交"); } } catch (Exception e) { return ServiceResult.fail(e.getMessage()); } finally { lock.unlock(); } } ``` ### 2. 在service层新建无事务方法 原理和1相同,使用无事务方法加锁后调用有事务方法。