事务与锁的顺序不对导致并发的问题

错误使用锁和事务导致并发

在事务中添加锁来解决并发的问题,这并没有解决并发的问题。

@Transactional
@Override
public void execute(){
    try {
        lock.lock()// 开启锁
        // 查询出数据
        mapper.select();
        // 根据查询出数据计算并写入到数据库中
        mapper.udpate()
    } finally {
        lock.unlock()
    }
}

比如数据库中count =100

  1. A线程进入当前语句执行,开启事务,获取锁,查询到count为100,扣减1,此时的count为99,锁释放,
  2. 此时B线程就能进入获取到锁,并且查询到数据count为100。A线程提交事务,此时数据库中的count为99
  3. B线程扣减1得到count为99,此时B线程将count值更新到数据库中,锁释放,提交事务
  4. 最后数据库得到count为99,但是执行了两次业务操作

这个原因是锁先释放掉了,但是事务没有提交,而mysql数据库库的隔离级别是可重复度,其他事务读取的数据未被改变的数据,读到的依旧是100。但锁被释放掉了时,其它线程立刻获取获取锁,此时读过来的数据还是原来的数据,导致该问题。

解决方式

加锁是为了让执行程序变成串行

  1. 将锁放到事务方面,让事务的执行变成串行就可以解决该问题。
  2. 数据库中串行的隔离级别也可以,就是在读数据时,添加了锁,其它事务在读取时,等待读锁。其实就是将并行变成了串行
@Service
public class A{
    @Resource B b;
    
    public void serviceA(){
        try{
            lock.lock()
            b.serviceB();
        } finally {
            lock.unLock()
        }
    }
} 

@Service
public class B{
    @Transactional
    public void serviceB() {
       // 查询出数据
        mapper.select();
        // 根据查询出数据计算并写入到数据库中
        mapper.udpate()      
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值