# 事务相关配置

属性作用示例
readOnly设置是否为只读事务readOnly=true 只读事务
timeout设置事务超时时间timeout = -1 (永不超时)
<font style="color:red">rollackFor</font>设置事务回滚异常 (class)rollbackFor=(NullPointException.class)
rollbackForClassName设置事务回滚异常 (String)同上格式为字符串
noRollbackFor设置事务不回滚异常 (class)noRollbackFor=(NullPointerException.class)
noRollbackForClassName设置事务不会滚异常 (String)同上格式为字符串
propagation设置事务传播行为...

# 操作步骤

1. 对需要开启事物的方法加上注解式事务 @Transaction

@SuppressWarnings("all")
public interface UserService {
//    开启事务
    @Transactional
    void transfer(String p1,String p2,int monery);
}

2. 在业务层实现类中创造一个异常

@SuppressWarnings("all")
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    public void transfer(String p1,String p2,int monery){
        userMapper.transfer0(monery,p1);
        System.out.println(1/0);
        userMapper.transfer1(monery,p2);
    }
}

Run Result

image_2023-02-27-21-18-01

查看数据库

image_2023-02-27-21-18-43

3. 在业务层实现类中换一个异常

  • IOException 异常不能直接创建,我们需要使用特殊手段来创建它
@SuppressWarnings("all")
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    public void transfer(String p1,String p2,int monery) throws IOException {
        userMapper.transfer0(monery,p1);
        if(true){throw new IOException();}
        userMapper.transfer1(monery,p2);
    }
}

Run Test Class

Run Result

image_2023-02-27-21-21-34

查看数据库

image_2023-02-27-21-22-06

<font style="color:red"> 结论:有些异常 Spring 事务光靠 @Transaction 是不行的还是回发生不同步成功或失败的情况 </font>

<font style="color:red"> 在 @Transaction 中设置事务回滚异常 rollbackFor</font>

@SuppressWarnings("all")
public interface UserService {
//    开启事务
    @Transactional(rollbackFor = {IOException.class})
    void transfer(String p1,String p2,int monery) throws IOException;
}

Run Test Class

image_2023-02-27-21-27-34

Run Result

image_2023-02-27-21-27-58

# 转账业务追加日志

需求:实现任意两个账户间转账操作,并对每次转账操作在数据库进行留痕

需求微缩:A 账户减钱,B 账户加钱,数据库记录日志

分析:

  1. 基于转账操作案例添加日志模块,实现数据库中记录日志

  2. 业务层转账操作(transfer), 调用减钱,价钱与记录日志功能

# 实现效果预期:

无论转账操作是否成功,均进行转账操作的日志留痕

存在的问题:

日志的记录与转账操作隶属同一个事务,同成功,同失败

image_2023-02-27-22-25-19

# 事务的转播行为

  • 在业务层接口上添加 Spring 事务,设置事务传播行为 REQUIRES_NEW (需要新事务)

  • propagation = propagarion.REQUIRES_NEW

  • 事务传播行为:事务协调员对事物管理员所携带事务的处理态度

传播属性事务管理员事务协调员
REQUIRED (默认)开始 T<br> 无加入 T<br> 新建 T2
REQUIRES_NEW开启 T<br> 无新建 T2<br> 新建 T2
SUPPORTS开启 T<br> 无加入 T<br> 无
NOT_SUPPORTED开启 T<br> 无无 <br> 无
MANDATORY开启 T<br> 无加入 T<br>ERROR
NEVER开启 T<br> 无ERROR<br> 无
NESTED设置 savePoint, 一旦事务回滚,事务将回滚到 savePoint 处,交由客户响应提交 / 回滚
  • 传播行就是:事务协调员,针对事务管理员带的事务的一种态度,你有我加入,你没有我新建,而 REQUIRES_NEW 就是你有我新建,你没有我更要新建

image_2023-02-28-09-12-42

@SuppressWarnings("all")
public interface LogService {
//        新建一个事务不与其它事务为一组
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void log(String out,String in,int monery);
}

执行测试代码后,查看数据库

image_2023-02-28-09-25-23