事务隔离级别与传播行为

参考 JUide 大神的学习笔记


何为事务?

一言蔽之,事务是逻辑上的一组操作,要么都执行,要么都不执行,感觉有点原子性的意思。


何为数据库事务?

简单来说:多个SQL 语句 要么全部执行成功,要么全部不执行 。

# 开启一个事务
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;

什么是ACID?

关系型数据库事务都有 ACID 特性:

  • 原子性(Atomicity) : [ˌætəˈmɪsəti] ,事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 一致性(Consistency): [kənˈsɪstənsi] ,执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  • 隔离性(Isolation): [ˌaɪsəˈleɪʃn],并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  • 持久性(Durability):[ˌdjʊərəˈbɪləti] , 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

数据事务的实现原理呢?

我们这里以 MySQL 的 InnoDB 引擎为例来简单说一下。

MySQL InnoDB 引擎
使用 undo log(回滚日志) 来保证事务的原子性
使用 redo log(重做日志) 保证事务的持久性
通过 锁机制MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )

保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。


并发事务带来哪些问题?

1, 脏读(Dirty read):

  1. 一个事务(A)读取到另一个事务(B)中 未提交的数据 。(B)中事务中数据可能进行了改变,此时(A)事务读取的数据可能和数据库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫做脏读。

2. 不可重复读(Unrepeatable read):

  1. 主要针对的是 某行数据 ( 或 行中某列 ).
  2. 主要针对的操作是 修改操作.
  3. 两次读取在同一个事务内
  4. 当事务A 第一次读取事务后,事务B 对事务A 读取的数据进行修改,事务A 中再次读取的数据和之前读取的数据不一致,过程不可重复读。

3.幻读(Phantom read):

  1. 主要针对的操作是 新增删除
  2. 两次事务的结果.
  3. 事务A 按照特定条件查询出结果,事务B 新增了一条符合条件的数据。事务A 中查询的数据和数据库中的数据不一致的,事务A 好像出现了幻觉,这种情况称为幻读。

事务隔离级别

在多线程并发访问下如何保证访问到的数据具有完整性的?

1 . 读未提交 READ_UNCOMMITTED

最低的隔离级别,因为它允许读取尚未提交的数据变更,可能会导致脏读、不可重复读、幻读
通常情况下不会用到该级别。

2 .已提交读 READ_COMMITTED :

允许读取已经提交的数据,可以阻止脏读,可能会导致不可重复读、幻读

3 .可重复读 REPEATABLE_READ

同一字段 的多次读取结果都是一致的,除非数据是被本身事务自己所修改。可以阻止脏读和不可重复读,可能会导致幻读

4 .串行化 SERIALIZABLE

最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,事务之间完全不可能产生干扰,可以防止脏读、不可重复读,幻读。但是这将严重影响程序的性能。通常情况下不会用到该级别。


MySQL 默认采用的 可重复读REPEATABLE_READ 隔离级别
Oracle 默认采用的已提交读 READ_COMMITTED 隔离级别


事务传播行为.

事务传播行为是为了解决业务层方法之间互相调用事务问题

当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异常?)

MANDATORY:     [ˈmændətəri],如果当前上下文有事务,加入事务,如果当前上下文没有事务,报错。 即保证→ 调用此方法时必须和上下文在同一个事务里

NEVER:         如果当前上下文有事务,报错; 如果当前上下文没有事务,正常执行。 即保证→ 新的方法在没有事务的上下文中执行

------------------------------------------------------------------------------------------

SUPPORTS:      [səˈport],如果当前上下文有事务,加入事务;如果当前上下文没有事务,就在非事务状态下执行。 即 → 无所谓有没有事务的

REQUIRED:      (默认值)如果当前上下文有事务,加入事务;如果当前上下文没有事务,新建一个事务。 即保证 → 新的方法必须要有事务

------------------------------------------------------------------------------------------

NOT_SUPPORTED: 如果当前上下文有事务,把当前上下文事务挂起;如果当前上下文没有事务,正常执行。 即保证 → 新的方法在没有事务的环境中执行

REQUIRES_NEW:  如果当前上下文有事务,把当前上下文事务挂起,新建事务;如果当前上下文没有事务,新建事务,执行当前新建事务完成以后,上下文事务恢复再执行。即保证 → 新的方法必须要有独立的事务

------------------------------------------------------------------------------------------

NESTED:        [ˈnestɪd],如果当前上下文有事务,创建一个嵌套事务.如果当前上下文没有事务,新建事务

参考:事务的嵌套

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值