跳到主要内容

01、分布式事务 实战 - 本地事务

一 什么是事务

逻辑上的一组操作,组成这个操作的各个逻辑单元要么一起成功,要么一起失败。

二 事务的四大特性

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

总结