SpringBoot系列—@Transactional 事务管理

关系型数据库遵循ACID规则

事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

Transactional参数解析

@Transactional(readOnly = false,propagation = Propagation.REQUIRED,rollbackFor = Exception.class)

propagation 传播行为:

REQUIRED:Support a current transaction, create a new one if none exists【支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择】
SUPPORTS:Support a current transaction, execute non-transactionally if none exists.【支持当前事务,如果当前没有事务,就以非事务方式执行】
MANDATORY:Support a current transaction, throw an exception if none exists.【支持当前事务,如果当前没有事务,就抛出异常】
REQUIRES_NEW:Create a new transaction, and suspend the current transaction if one exists.【 新建事务,如果当前存在事务,把当前事务挂起】
NOT_SUPPORTED:Execute non-transactionally, suspend the current transaction if one exists【 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起】
NEVER:Execute non-transactionally, throw an exception if a transaction exists【以非事务方式执行,如果当前存在事务,则抛出异常】
NESTED:Execute within a nested transaction if a current transaction exists,behave like REQUIRED【如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作】
理解1:嵌套事务隔离级别(假如有两个业务接口 ServiceA 和 ServiceB, 其中 ServiceA 中有一个方法实现如下 
void methodA() { 
// 调用 ServiceB 的方法 
ServiceB.methodB(); 
}//参考博文:http://www.iteye.com/topic/35907/)
PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行. 
    另一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务,  它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,  它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交. 
    由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于 roll back.

@Transactional注解事务失效的解决方案

Spring的事务传播策略在内部方法调用时将不起作用
mysql关闭自动提交
mysql的驱动用 com.mysql.jdbc.Driver(com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource不支持事务?)
用非root权限的普通权限的用户连接mysql
@Transactional 注解只能应用到 public 可见度的方法上
必须在配置文件中使用配置元素,才真正开启了事务行为
数据库引擎要支持事务


你可能感兴趣的:(SpringBoot)