一 什么是事务
逻辑上的一组操作,组成这个操作的各个逻辑单元要么一起成功,要么一起失败。
二 事务的四大特性
1. 原子性(Atomicity)
操作的不可拆分,事务中的所有操作,要么一起执行,要么一起不执行。
2. 一致性(Consistency)
所有数据都满足业务规则的一致状态:事务开始之前数据是正确的,事务结束之后数据也是正确的。如果事务执行的过程中,有几个操作失败了,则所有操作都必须撤销---回滚。
3. 隔离性(Isolation)
多个事务在并发执行过程中不能相互干扰。
4. 持久性(Durability)
事务执行结束后,对数据的修改应该永久保存下来,不会因系统错误或其他意外而受到影响。通常情况下,应该写入到持久化容器中。
三 什么是本地事务
事务只在本工程内有效(不能跨工程,后面会讲分布式事务),本地事务依赖于数据库事务。
四 隔离级别
脏读:一个事务读取的另一个事务未提交的数据。
不可重复读:一个事务读取到另一个事务已提交的数据,单条记录前后不匹配。
幻读(虚读):一个事务读取到另一个事务已提交的数据,多读到几条记录。
不可重复读与幻读的区别: 不可重复读前后读取的数据内容不一致,幻读前后读取的数据量不一致。
- 解决读的问题:在数据库层面设置事务隔离级别
隔离级别 | 脏读 | 不可重复的 | 幻读(虚读) |
---|---|---|---|
读未提交 | 是 | 是 | 是 |
读提交 | 否 | 是 | 是 |
可重复读 | 否 | 否 | 是 |
序列化 | 否 | 否 | 否 |
4.1 MySql 修改隔离级别
查看全局事务隔离级别:SELECT @@global.tx_isolation
设置全局事务隔离级别:set global transaction isolation level read committed;
查看当前会话事务隔离级别:SELECT @@tx_isolation
设置当前会话事务隔离级别:set session transaction isolation level read committed;
查看mysql默认自动提交状态:select @@autocommit
设置mysql默认自动提交状态:set autocommit = 0;【不自动提交】
开启一个事务:start transaction;
提交事务:commit
回滚事务: rollback
在事务中创建一个保存点:savepoint tx1
回滚到保存点:rollback to tx1
五 事务的传播行为
事务之间的相互调用,一个事务出错回滚,其他事务需不需要回滚,就取决于传播行为级别的设置。
5.1 七种传播行为
级别 | 效果 |
---|---|
REQUIRED | 支持当前事务,如果不存在,就新建一个 |
SUPPORTS | 支持当前事务,如果不存在,就不使用事务 |
MANDATORY | 支持当前事务,如果不存在,抛出异常 |
REQUIRES_NEW | 如果有事务存在,挂起当前事务,创建一个新的事务 |
NOT_SUPPORTED | 以非事务方式运行,如果有事务存在,挂起当前事务 |
NEVER | 以非事务方式运行,如果有事务存在,抛出异常 |
NESTED | 如果当前事务存在,则嵌套事务执行(嵌套式事务) |
- NESTED
依赖于JDBC3.0提供的SavePoint技术
eg:删除用户 删除订单。在删除订单后,设置savePoint,执行删除用户。删除订单和删除用户在同一事务中,删除用户失败,事务回滚savePoint,由用户控制视图提交还是回滚。 - 这七种事务传播机制最常用的就两种:
REQUIRED:一个事务,要么成功,要么失败。
REQUIRES_NEW:两个不同事务,彼此之间没有关系。一个事务失败了不影响另一个事务。
六 回滚策略
@Transactional 默认情况下的回滚策略:
- 运行时异常:不受检异常,没有强制要求try-catch,都会回滚。例如:ArrayOutOfIndex,OutofMemory,NullPointException
- 编译时异常:受检异常,必须处理,要么try-catch要么throws,都不回滚。例如:FileNotFoundException
指定回滚策略:
- rollbackFor:指定的异常必须回滚
- noRollbackFor:发生指定的异常不用回滚
七 超时事务
设置timeout,事务运行超时就抛出异常
八 只读事务
readOnly=true事务,则代表该方法只能查询,不能增删改。readOnly默认为false