Solon详解(四)- Solon的事务传播机制
在前面的篇章里我们已经见识了 Solon 对事务的控制,及其优雅曼妙的形态。该篇将对事务的传播机制做讲解。出于对用户的学习成本考虑,Solon 借签了Spring 的事务传播策略;并友好的支持多数据源事务。
一、为什么要有传播机制?
Solon 的事务是基于 aop 实现的,用者不用关心事务的开始、提交、回滚,只需要在方法上加 @XTran 注解。因为看不到内部情况,所以也会有些疑问:
- 场景一:方法A调用了方法B,但两个方法都有事务,这个时候如果方法B异常:
- 是让方法B回滚,还是两个一起回滚?
- 场景二:方法A调用了方法B,但是只有方法A加了事务:
- 是否让方法B也加入方法A的事务?
- 如果方法B异常,是否回滚方法A?
- 场景三:方法A调用了方法B,两者都有事务,方法B已经正常执行完:
- 但方法A异常,是否需要回滚方法B的数据?
这个时候事务的传播机制和策略就派上用场了。
二、传播机制生效条件与特点!
基于 aop 来代理事务控制的方案 ,大都是针对于接口或类的之间调用才起效的;所以在同一个类中两个方法之间的调用,传播机制是无效的。了解这一点很重要,不然容易出乌龙事件。
- 特点1:Solon 的事务传播策略与Spring差不多(出于对新用户的学习成本考虑)
- 特点2:Solon 可方便的支持多数据源事务
- 特点3:Solon 可方便支持分库框架或中间件的事务
三、传播机制的策略
下面的类型都是针对于被调用方法来说的,理解起来要想象成两个 service 方法的调用才可以。
| 传番策略 | 说明 |
|---|---|
| @XTran(group=true) | 如果当前没有事务组,则新建一个事务组;可用于管理多数据源事务,但不会建立链接 |
| @XTran(policy=TranPolicy.required) | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。也是默认。 |
| @XTran(policy=TranPolicy.requires_new) | 新建事务,如果当前存在事务,把当前事务挂起。 |
| @XTran(policy=TranPolicy.nested) | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与required类似的操作。 |
| @XTran(policy=TranPolicy.mandatory) | 使用当前的事务,如果当前没有事务,就抛出异常。 |
| @XTran(policy=TranPolicy.supports) | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
| @XTran(policy=TranPolicy.not_supported) | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
| @XTran(policy=TranPolicy.never) | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
- 补充1:如果当前为事务组,required 和 nested 策略的事务,会自动加入事务组
- 补充2:group=true 有时候可当 required 用
- 补充3:一般最常用的是 @XTran(group = true) 和 @Tran 的组合使用
四、XTran 属性说明
| 属性 | 说明 |
|---|---|
| value | 数据源标识 |
| policy | 事务策略 |
| group | 是否为事务组;用于管理下属的子事务 |
五、示例
- 父回滚,子回滚
@XService
public class UserService{
@XTran
public void addUser(UserModel user){
//....
}
}
@XController
public class DemoController{
@XInject
UserService userService;
//父回滚,子回滚
//
@XTran(group = true)
@XMapping("/user/add")
pubblic void addUser(UserModel user){
userService.addUser(user);
throw new RuntimeException("不让你加");
}
//父回滚,子回滚
//
@XTran
@XMapping("/user/add2")
pubblic void addUser2(UserModel user){
userService.addUser(user);
throw new RuntimeException("不让你加");
}
}
- 父回滚,子不回滚
@XService
public class UserService{
@XTran(policy = TranPolicy.requires_new)
public void addUser(UserModel user){
//....
}
}
@XController
public class DemoController{
@XInject
UserService userService;
//父回滚,子不回滚
//
@XTran(group = true)
@XMapping("/user/add")
pubblic void addUser(UserModel user){
userService.addUser(user);
throw new RuntimeException("不让你加;但还是加了:(");
}
//父回滚,子不回滚
//
@XTran
@XMapping("/user/add2")
pubblic void addUser2(UserModel user){
userService.addUser(user);
throw new RuntimeException("不让你加;但还是加了:(");
}
}
- 子回滚父不回滚
@XService
public class UserService{
@XTran(policy = TranPolicy.nested)
public void addUser(UserModel user){
//....
throw new RuntimeException("不让你加");
}
}
@XController
public class DemoController{
@XInject
UserService userService;
//子回滚父不回滚
//
@XTran(group = true)
@XMapping("/user/add")
pubblic void addUser(UserModel user){
try{
userService.addUser(user);
}catch(ex){ }
}
//子回滚父不回滚
//
@XTran
@XMapping("/user/add2")
pubblic void addUser2(UserModel user){
try{
userService.addUser(user);
}catch(ex){ }
}
}
- 多数据源事务示例
@XService
public class UserService{
@XTran("db1")
public void addUser(UserModel user){
//....
}
}
@XService
public class AccountService{
@XTran("db2")
public void addAccount(UserModel user){
//....
}
}
@XController
public class DemoController{
@XInject
AccountService accountService;
@XInject
UserService userService;
@XTran(group = true)
@XMapping("/user/add")
pubblic void addUser(UserModel user){
userService.addUser(user); //会执行db1事务
accountService.addAccount(user); //会执行db2事务
}
}
Solon详解(四)- Solon的事务传播机制的更多相关文章
- MySQL系列详解四:MySQL事务-技术流ken
MySQL 事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数 ...
- Springboot mini - Solon详解(四)- Solon的事务传播机制
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- Solon详解(六)- Solon的校验扩展框架使用与扩展
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(二)- Solon的核心
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(三)- Solon的web开发
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(八)- Solon的缓存框架使用和定制
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(九)- 渲染控制之定制统一的接口输出
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(十)- 怎么用 Solon 开发基于 undertow jsp tld 的项目?
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
随机推荐
- 网络通信机制:Socket、TCP/IP、HTTP
13.1.1 TCP/IP协议 讲的很抽象,没具体看懂什么是TCP协议,什么是IP协议.IP协议保证消息从一个主机传送到另一个主机,消息在传送的过程中被分割成一个个小包,TCP协议会让两台相互连接的计 ...
- Btree索引和Hash索引
B-Tree 索引 BTree索引是最常用的mysql数据库索引算法,因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符, ...
- 10-9 重要的内置函数(zip、filter、map、sorted)
reverse----reversed l = [1,2,3,4,5,6] l.reverse() #不会保留原列表 print(l) l =[1,2,3,4,5,6] l2 = reversed(l ...
- PHP xml_set_external_entity_ref_handler() 函数
定义和用法 xml_set_external_entity_ref_handler() 函数规定当解析器在 XML 文档中找到外部实体时被调用的函数. 如果成功,该函数则返回 TRUE.如果失败,则返 ...
- PHP getNamespaces() 函数
实例 返回 XML 文档中使用的命名空间: <?php$xml=<<<XML高佣联盟 www.cgewang.com<?xml version="1.0&quo ...
- luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树
LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...
- 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量
LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...
- 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘
一.前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的 ...
- ThreadLocal面试六连问
转自:码农沉思录 中高级阶段开发者出去面试,应该躲不开ThreadLocal相关问题,本文就常见问题做出一些解答,欢迎留言探讨. ThreadLocal为Java并发提供了一个新的思路, 它用来存储T ...
- 【BZOJ4631】踩气球 题解(线段树)
题目链接 ---------------------- 题目大意:给定一个长度为$n$的序列${a_i}$.现在有$m$个区间$[l_i,r_i]$和$q$个操作,每次选取一个$x$使得$a_x--$ ...