Spring事务中的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);
    }
    

版权声明:本文为Rambo_Yang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。