【发布时间】:2021-07-17 06:17:49
【问题描述】:
今天在学习使用'reentrant lock'锁的时候,遇到了一个问题。将锁添加到已售商品业务的代码中。
@Service
public class ServiceOne{
private Lock lock = new ReentrantLock(true);
public Result func(long seckillId, long userId) {
lock.lock();
// Check stock
// sale
// Reduce stock
lock.unlock();
}
}
前提是使用MySQL数据库的重读隔离机制。在高并发的情况下,假设有多个线程同时调用该方法。当交易在'lock'和'unlock'之间可以完全打开和提交时,就不存在超卖问题了。
显然,事务必须在'lock'之后才开始,所以关键是事务是否必须在'unlock'之前提交。 如果是在'unlock'之后,那么就真的有可能超卖了:比如线程1执行完方法,但是事务还没有提交,线程2拿到锁,开始执行方法。在“可重复读”隔离机制下,线程2无法读取线程1对store的操作结果,因此超卖。
希望你能来回答你的问题!感激不尽!
【问题讨论】:
-
@Transactional被实现为“环绕”建议。