# 事务相关配置
属性 | 作用 | 示例 |
---|---|---|
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
查看数据库
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
查看数据库
<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
Run Result
# 转账业务追加日志
需求:实现任意两个账户间转账操作,并对每次转账操作在数据库进行留痕
需求微缩:A 账户减钱,B 账户加钱,数据库记录日志
分析:
基于转账操作案例添加日志模块,实现数据库中记录日志
业务层转账操作(transfer), 调用减钱,价钱与记录日志功能
# 实现效果预期:
无论转账操作是否成功,均进行转账操作的日志留痕
存在的问题:
日志的记录与转账操作隶属同一个事务,同成功,同失败
# 事务的转播行为
在业务层接口上添加 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 就是你有我新建,你没有我更要新建
@SuppressWarnings("all") | |
public interface LogService { | |
// 新建一个事务不与其它事务为一组 | |
@Transactional(propagation = Propagation.REQUIRES_NEW) | |
void log(String out,String in,int monery); | |
} |
执行测试代码后,查看数据库