You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

41 lines
1.1 KiB

# 一、在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相同使用无事务方法加锁后调用有事务方法。