Spring事务中的Synchronized同步为什么不生效

本文探讨了在Java开发中,多线程环境下事务与synchronized同步可能导致的问题。当事务在同步代码块之前开启,如果在同步方法执行结束与事务提交之间有其他线程介入,可能会导致数据不一致。解决方案是调整代码,确保同步代码块在事务开始之前执行,以保证线程安全和数据一致性。

一、场景描述
  • 在实际开发过程中,为解决程序处理业务的性能问题,多线程的场景是十分常见的

  • 随着业务的复杂,在处理多线程安全问题和业务数据一致性问题,可能会出现线程同步和事务混合使用的情况

  • 也正是因为这种不规范或者不懂原理的混合使用,会导致 synchronized 不生效的问题

  • 代码片段:

    @Transactional(rollbackFor = Exception.class)
    public void testSynchronized() {
    	saveOrUpdate(1);
    }
    
    // 方法同步
    public synchronized void saveOrUpdate(int userId) {
    	User user = UserDao.queryUserById(userId);
    	user.setName = "Rambo";
    	UserDao.insertUser(user);
    }
    
二、问题解析
  • 事务开启在同步代码块之前
  • 事务是 SpringAOP 开启的,进入方法前,AOP 就开启了事务
  • 事务开启以后才进入方法,再进入同步代码块加锁
  • 当同步方法执行结束后,释放锁并提交事物(问题就出现在这里:如果在释放锁和提交事物之间有其它的线程请求,那么处理后的数据没有被提交,导致 synchronized 同步不生效的问题)
    1
三、解决方案
  • 同步代码块在事物之前开启
    // 方法同步
    public synchronized void testSynchronized() {
    	saveOrUpdate(1);
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(int userId) {
    	User user = UserDao.queryUserById(userId);
    	user.setName = "Rambo";
    	UserDao.insertUser(user);
    }
    
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值