欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

锁与事务的关系

程序员文章站 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])咨询。