一、错误姿势

锁放在事务中,是错误的

@Transactional(rollbackFor = Exception.class)
//创建订单
public Result creatOrder(Long userId){  
	//加锁,一个用户只能买一次
	synchronized(userId.toString().intern()){
		//1.查询订单数据,判断用户是否已经购买过了
		//2.查询库存
		//3.减少库存
	}
}

锁在事务方法中,这种情况下会出现一个问题:

事务提交的时机,可能是在锁释放前,也可能是在锁释放后

  1. 事务先提交然后释放锁,那就没问题,因为这时候,其他线程只能在事务提交后且锁释放后,获取都锁操作数据。

  2. 先释放锁然后事务提交完毕,就存在问题。先释放了锁,但是事务还没提交完毕,其他线程提前获取到了锁资源进行数据操作,就会发生数据错乱问题。

二、正确姿势

把事务,放在锁内

public createOrder(Long userId){
	//加锁,一个用户只能买一次
	synchronized(userId.toString().intern()){
		//获取当前类的代理类,然后调用事务方法,才能使事务生效
		OrderService orderServiceProxy=(OrderService)AopContext..currentProxy();
		return orderServiceProxy.doCreateOder(userId);
	}
}


//事务方法
@Transactional(rollbackFor = Exception.class)
//创建订单
public Result doCreatOrder(Long userId){  
		//1.查询订单数据,判断用户是否已经购买过了
		//2.查询库存
		//3.减少库存
}

在这种情况,才能保证,事务提交发生的时机一定是在锁释放前

二、扩展

常见事务失效情况

文章作者: 落叶知秋
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落叶知秋
喜欢就支持一下吧