关于@Transactional注释的方法中使用Synchronized代码块失效的问题

6 篇文章 0 订阅

对方法使用声明式事务@Transactional,方法伪代码如下

@Transcational
public void method(){
    ...
    synchronized (obj){
        //修改某条数据状态为锁定状态
        entity = mapper.select();
        if(entity.status == 0){
            entity.status = 1;
            mapper.update(entity);
        }
    }
    //其他操作
    ...
}

场景: 如锁定库中某条数据,使多线程竞争安全的情况下使用同步代码块

原因:线程A锁定操作的同步代码块已执行完成并继续进行其他操作时事务是未提交状态,线程B此时进入方法并进入同步代码块中,因线程A事务未提交,mysql默认隔离级别是可重复读,查询出的结果是未锁定状态,进行锁定就产生了重复锁定的问题。

解决方法:

1.将同步代码块范围扩大至方法结束

2.同步代码块内方法开启一个新事务,即@Transcational传播机制为REQUIRED_NEW,但需要注意事务aop嵌套问题

3.不使用数据库操作锁定数据 比如缓存锁定数据

4.将事务的隔离级别设置为读未提交(read uncommited ),此时就算未提交事务,在其他事务中读取该值也是修改后的状态 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值