工作事务常出现的问题

一 锁加在事务之内

@Transactional(rollbackFor = Exception.class)
 public void addError(User user) {
    
    
      log.info("add user params user:{}", JSON.toJSONString(user));
      Assert.isTrue(StringUtils.isNotBlank(user.getIdCard()), "身份证号不允许null");
      String key = "key";
      RLock lock = redissonClient.getLock(key);
      lock.lock();
      try {
    
    
          LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                  .eq(User::getIdCard, user.getIdCard());
          long count = userMapper.selectCount(wrapper);
          if (count == 0) {
    
    
              userMapper.insert(user);
          }
      } catch (Exception e) {
    
    
          log.error("add user error", e);
      } finally {
    
    
          lock.unlock();
      }
      System.out.println("并发执行,同时插入了两条");
}

在线程1释放锁后事务还没提交,数据库没有内容
线程2获取锁执行逻辑,查询数据库没有需要锁的值
最终结果插入两条

二 错误的事务传播

a服务

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void a() {
    
    
        try {
    
    
            userServiceB.b();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        User user = new User();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getIdCard, "1000");
        User user1 = userMapper.selectOne(wrapper);
        user1.setName("zhangsan");
        userMapper.updateById(user1);
    }

b服务

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void b() {
    
    
        User user = new User();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getIdCard, "1000");
        User user1 = userMapper.selectOne(wrapper);
        user1.setName("lisi");
        userMapper.updateById(user1);
        System.out.println(1 / 0);
    }

报错:

2023-03-21 14:24:25 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.etTransaction 370 : Creating new transaction with name [com.lx.debug.idempotent.moduler.service.impl.UserServiceAImpl.a]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
2023-03-21 14:24:25  INFO - [          main] com.zaxxer.hikari.HikariDataSource      .getConnection 110 : HikariPool-1 - Starting...
2023-03-21 14:24:25  WARN - [          main] com.zaxxer.hikari.util.DriverDataSource .       <init>  70 : Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation.
2023-03-21 14:24:25  INFO - [          main] com.zaxxer.hikari.HikariDataSource      .getConnection 123 : HikariPool-1 - Start completed.
2023-03-21 14:24:25 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.      doBegin 267 : Acquired Connection [HikariProxyConnection@1514631948 wrapping com.mysql.cj.jdbc.ConnectionImpl@15369d73] for JDBC transaction
2023-03-21 14:24:25 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.      doBegin 285 : Switching JDBC Connection [HikariProxyConnection@1514631948 wrapping com.mysql.cj.jdbc.ConnectionImpl@15369d73] to manual commit
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.ngTransaction 470 : Participating in existing transaction
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : ==>  Preparing: SELECT id,name,id_card,age,email,is_delete FROM user WHERE is_delete=0 AND (id_card = ?)
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : ==> Parameters: 1000(String)
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : <==      Total: 1
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : ==>  Preparing: UPDATE user SET name=?, id_card=?, age=?, email=? WHERE id=? AND is_delete=0
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : ==> Parameters: lisi(String), 1000(String), 1(Integer), 1(String), 1000(Long)
java.lang.ArithmeticException: / by zero
	at com.lx.debug.idempotent.moduler.service.impl.UserServiceBImpl.b(UserServiceBImpl.java:30)

2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : <==    Updates: 1
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.ocessRollback 842 : Participating transaction failed - marking existing transaction as rollback-only
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.tRollbackOnly 359 : Setting JDBC transaction [HikariProxyConnection@1514631948 wrapping com.mysql.cj.jdbc.ConnectionImpl@15369d73] rollback-only
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : ==>  Preparing: SELECT id,name,id_card,age,email,is_delete FROM user WHERE is_delete=0 AND (id_card = ?)
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : ==> Parameters: 1000(String)
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.selectList.        debug 137 : <==      Total: 1
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : ==>  Preparing: UPDATE user SET name=?, id_card=?, age=?, email=? WHERE id=? AND is_delete=0
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : ==> Parameters: zhangsan(String), 1000(String), 1(Integer), 1(String), 1000(Long)
2023-03-21 14:24:26 DEBUG - [          main] ent.moduler.mapper.UserMapper.updateById.        debug 137 : <==    Updates: 1
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.       commit 705 : Global transaction is marked as rollback-only but transactional code requested commit
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.ocessRollback 833 : Initiating transaction rollback
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.   doRollback 345 : Rolling back JDBC transaction on Connection [HikariProxyConnection@1514631948 wrapping com.mysql.cj.jdbc.ConnectionImpl@15369d73]
2023-03-21 14:24:26 DEBUG - [          main] work.jdbc.support.JdbcTransactionManager.terCompletion 389 : Releasing JDBC Connection [HikariProxyConnection@1514631948 wrapping com.mysql.cj.jdbc.ConnectionImpl@15369d73] after transaction

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:870)

从日志可以看出
B服务提交的时候将当前事务标记为回滚

marking existing transaction as rollback-only

A服务捕获住异常后提交事务,发现当前事务被标记为 rollback-only
随后抛出异常,A服务既没有提交,也没有回滚

猜你喜欢

转载自blog.csdn.net/lx9876lx/article/details/129690022