锁与事务的关系
程序员文章站
2024-01-14 17:13:58
...
在并发场景下, 我们往往需要在事务方法中加锁来应对并发.如下.下面以 ReentrantLock 为例子.
public final static ReentrantLock MY_LOCK= new ReentrantLock();
@Transactional
public Result doWork(String busiId) {
try {
MY_LOCK.lock();
// 具体的业务逻辑
} catch (Exception e) {
e.printStackTrace();
} finally{
MY_LOCK.unlock()
}
return Result.ok();
}
但是在并发量较大的时候, 会发现出现问题.如秒杀商品场景的话, 会出现超卖的问题.这是因为 ReentrantLock的加/解锁操作是在事务方法内部进行的. 也就是说, 在 unlock()进行后, 事务不一定会提交. 这样就出现问题了.同样, 如果是分布式锁,即便是有网络延迟,但还是不严谨的.
处理方法: 锁上移. 可以在Controller中对方法加锁.
public final static ReentrantLock MY_LOCK= new ReentrantLock();
@RequestMapping("doWork")
@ResponseBody
public String doWork(String busiId){
Result ret = new Result();
try{
MY_LOCK.lock();
ret = myService.doWork(busiId)
}finally {
MY_LOCK.unlock();
}
return ret ;
}
还有一种优雅的方式, aop.在aop的切片中,事务的顺序是Ordered.LOWEST_PRECEDENCE.最后执行的.保证了我们定义的加锁aop会在事务切片前执行.
本文参考小柒的文章
----------
https://blog.52itstyle.vip/archives/2952/
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 如有问题, 可邮件([email protected])咨询。