2022-01-23 19:09:53
在Spring中,@Transactional注解的事务提交时间点是方法执行结束后。具体来说,Spring通过AOP(面向切面编程)框架实现事务管理,其核心流程如下:
若未抛出异常,则提交事务。
若抛出未捕获的异常,则回滚事务。
在并发环境中,若锁的释放(如lock.unlock())发生在事务提交之前,可能导致其他线程在事务未提交时读取到旧数据(如库存未减少),从而引发超卖。例如:
为避免超卖,需确保事务提交在锁释放之前。可通过以下方式重构代码:
public Result func(long seckillId, long userId) { lock.lock(); // 先加锁 try { // 1. 查询库存(当前线程可见,因锁阻塞其他线程) // 2. 减少库存(操作纳入事务) // 3. 方法返回时,Spring代理提交事务(在lock.unlock()之前) return Result.SUCCESS; } finally { lock.unlock(); // 事务已提交,其他线程可见最新数据 }}关键点:
通过理解事务提交时机与并发控制的结合,可以有效避免超卖等竞态条件问题。