Springboot min -Solon 详解系列文章:
Springboot mini - Solon详解(一)- 快速入门
Springboot mini - Solon详解(二)- Solon的核心
Springboot mini - Solon详解(三)- Solon的web开发html
在前面的篇章里咱们已经见识了 Springboot mini - Solon 对事务的控制,及其优雅曼妙的身姿。该篇将对事务及其处理策略进行详解。出于对用户的学习成本考虑,Solon 借签了Spring 的事务传播策略;因此体验上几乎同样。java
Solon 对事务的控制,是使用 aop 切面实现的,因此不用关心事务的开始,提交 ,回滚,只须要在方法上加 @Tran
注解便可。
由于这些都是暗的,看不见的,因此也容易产生一些疑惑:git
若是 classB 方法异常,是让 classB 方法提交,仍是两个一块儿回滚?
是否把 classB 也加入 classA 的事务,若是 classB 异常,是否回滚 classA?
是否须要回滚 classB 的数据?
这个时候,传说中的事务传播机制和策略就派上用场了github
全部用 aop 实现的事务控制方案 ,都是针对于接口或类的。因此在同一个类中两个方法的调用,传播机制是不生效的。web
下面的类型都是针对于被调用方法来讲的,理解起来要想象成两个 class 方法的调用才能够。并发
传番策略 | 说明 |
---|---|
TranPolicy.required | 支持当前事务,若是没有则建立一个新的。这是最多见的选择。也是默认。 |
TranPolicy.requires_new | 新建事务,若是当前存在事务,把当前事务挂起。 |
TranPolicy.nested | 若是当前有事务,则在当前事务内部嵌套一个事务;不然新建事务。 |
TranPolicy.mandatory | 支持当前事务,若是没有事务则报错。 |
TranPolicy.supports | 支持当前事务,若是没有则不使用事务。 |
TranPolicy.not_supported | 以无事务的方式执行,若是当前有事务则将其挂起。 |
TranPolicy.never | 以无事务的方式执行,若是当前有事务则报错。 |
属性 | 说明 |
---|---|
unspecified | 默认(JDBC默认) |
read_uncommitted | 脏读:其它事务,可读取未提交数据 |
read_committed | 只读取提交数据:其它事务,只能读取已提交数据 |
repeatable_read | 可重复读:保证在同一个事务中屡次读取一样数据的结果是同样的 |
serializable | 可串行化读:要求事务串行化执行,事务只能一个接着一个执行,不能并发执行 |
属性 | 说明 |
---|---|
policy | 事务传导策略 |
isolation | 事务隔离等级 |
readOnly | 是否为只读事务 |
@Service public class UserService{ @Tran public void addUser(UserModel user){ //.... } } @Controller public class DemoController{ @Inject UserService userService; //父回滚,子回滚 // @Tran @Mapping("/user/add2") pubblic void addUser2(UserModel user){ userService.addUser(user); throw new RuntimeException("不让你加"); } }
@Service public class UserService{ @Tran(policy = TranPolicy.requires_new) public void addUser(UserModel user){ //.... } } @Controller public class DemoController{ @Inject UserService userService; //父回滚,子不回滚 // @Tran @Mapping("/user/add2") pubblic void addUser2(UserModel user){ userService.addUser(user); throw new RuntimeException("不让你加;但仍是加了:("); } }
@Service public class UserService{ @Tran(policy = TranPolicy.nested) public void addUser(UserModel user){ //.... throw new RuntimeException("不让你加"); } } @Controller public class DemoController{ @Inject UserService userService; //子回滚父不回滚 // @Tran @Mapping("/user/add2") pubblic void addUser2(UserModel user){ try{ userService.addUser(user); }catch(ex){ } } }
@Service public class UserService{ @Db("db1") UserMapper userDao; @Tran public void addUser(UserModel user){ userDao.insert(user); } } @Service public class AccountService{ @Db("db2") AccountMappeer accountDao; @Tran public void addAccount(UserModel user){ accountDao.insert(user); } } @Controller public class DemoController{ @Inject AccountService accountService; @Inject UserService userService; @Tran @Mapping("/user/add") public void addUser(UserModel user){ userService.addUser(user); //会执行db1事务 accountService.addAccount(user); //会执行db2事务 } }