Spring @transactional注解和synchronized同步锁同时使用不能同步的问题

本文探讨了在Spring框架中,如何正确地结合使用事务管理和同步锁来确保数据的一致性和线程安全性。通过具体的代码示例,分析了不当的实现方式可能导致的问题,并提出了一种改进方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果在service层的方法上同时使用事务和同步锁无法保证数据同步

@Service  
public class Service{  
     @Transactional(readOnly = false)
     public void synchronized update() {  
         ............  
     }  
}  

*上面这个例子无法保证数据的一致性

由于spring的AOP的特性,会在update方法之前开启事务,之后再加锁,当锁住的代码执行完成后,在提交事务。

因此synchronized代码块执行是在事务之内执行的,可以推断在代码块执行完时,事务还未提交,因此其它线程进入synchronized代码块后,读取的数据库数据不是最新的。

为了解决上面的并发同步问题,可以通过synchronized方法调用update()方法,在还没有开事务之前就加同步锁,那么就可以保证线程同步。

1、原实现同步方法

同步方法或者同步方法块都不能达到同步的作用。

@Service  
public class Service{  
  
    @Transactional(readOnly = false,rollbackFor = SQLException.class)  
    public synchronized void synMethodOne() throws SQLException{  
        ............
    }       
}  
@Service  
public class Service{  
  
    @Transactional(readOnly = false,rollbackFor = SQLException.class)  
    public void synMethodTwo() throws SQLException{  
        synchronized(this){  
            ............   
        }  
    }       
} 

2、修改后的方法 

@Service  
public class noTransService {  
  
    @Autowired  
    SynchronizedService synchronizedService;  
      
    public synchronized void synMethod() throws SQLException{  
        synchronizedService.synMethodTwo();  
    }  
      
}  
  
  
@Service  
public class SynchronizedService{  
  
    @Transactional(readOnly = false,rollbackFor = SQLException.class)  
    public void synMethodTwo() throws SQLException{  
        ............   
    }  
      
}  

 

转载于:https://my.oschina.net/ljc94/blog/1610125

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值