MySQL事务

ACID

Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。

Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
一致性:这个讲的是事务是按照预期生效的,一致性的核心一部分是靠原子性实现的,而另一部分是逻辑实现。
比如转账,规定转账前后所有账户金额总额是不会变的,则A减少1000,B必须增加1000才能保证数据的一致性.

Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。

Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

事务隔离级别

在SQL标准中,定义了四个隔离级别:
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE

事务并发中带来的一下几个问题:
脏读(Dirty Read)、不可重复读(Non-repeatable Read)、幻读(Phantom Read)
InnoDB存储引擎默认支持REPEATABLE_READ.

事务的执行流程

开启一个事务.
执行一组操作.
如果都执行成功,那么提交并结束事务.
如果任何操作失败,那么回滚已经执行的操作,结束事务.

在事务执行过程中,如果出现故障,比如断电、宕机,这个时候就要利用日志(redo log 或者 undo log) 加上 checkpoint 来保证事务的完整结束。

隔离性

隔离性主要解决的问题是性能,或者更直接点,就是尽可能的降低受到锁影响的事务进程的个数的。

隔离性的本质就是一个锁的范围逐渐扩大,性能逐渐降低,但能提供更强级别的一致性保证的这么一个特征。

  • 数据库的四种隔离级别 可能出现的相应问题
    READ_UNCOMMITTED
    允许读取未提交的数据(对应未提交读),可能导致脏读、不可重复读、幻读.
    读未提交,允许另外一个事务可以看到这个事务未提交的数据。

READ_COMMITTED
允许在一个事务中读取另一个已经提交的事务中的数据(对应已提交读)。可以避免脏读,但是无法避免不可重复读和幻读.
读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。

REPEATABLE_READ
一个事务不可能更新由另一个事务修改但尚未提交(回滚)的数据(对应可重复读)。可以避免脏读和不可重复读,但无法避免幻读.
可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。

SERIALIZABLE
这种隔离级别是所有的事务都在一个执行队列中,依次顺序执行,而不是并行(对应可序列化)。可以避免脏读、不可重复读、幻读。但是这种隔离级别效率很低,因此,除非必须,否则不建议使用。
一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。

隔离级别脏读不可重复读幻读第一类丢失更新第二类丢失更新
读未提交允许允许允许不允许允许
读已提交不允许允许允许不允许允许
可重复读不允许不允许允许不允许不允许
序列化不允许不允许不允许不允许不允许

脏读

脏读就是指当一个事务T1正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中.
这时,另外一个事务T2也访问这个数据,然后使用了这个数据。
因为T1对这个数据是还没有提交的数据(T1可能会因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的),
那么事务T2读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

T1 修改 A
T2 读取 A
T1 撤销修改 A
由于T1并未真正修改A,导致T2读取到脏数据

不可重复读

在一个事务T1内,多次读同一个数据。在这个事务T1还没有结束时,另一个事务T2也访问该同一数据并修改数据。
那么,在事务T1的两次读数据之间。由于事务T2的修改,那么事务T1两次读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

T1 读 A
T2 修改 A
T1 再读 A,由于T2的修改,导致T1在一个事务内两次读到的数据是不一样

幻读

幻读是指当事务不是独立执行时发生的一种现象,
例如第一个事务T1对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。
同时,第二个事务T2也修改这个表中的数据,这种修改是向表中插入“一行新数据”。
那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样.

不可重复读 和 幻读 的区别

不可重复读: 主要是说多次读取一条记录, 发现该记录中某些列值被修改过。

幻读: 主要是说多次读取一个范围内的记录(包括直接查询所有记录结果或者做聚合统计), 发现结果数不一致(标记录增多或减).

InnoDB四种隔离级别

InnoDB隔离级别对应的问题和标准的隔离级别有些区别
MySQL/InnoDB定义的4种隔离级别:

Read Uncommited
可以读取未提交记录。此隔离级别,不会使用,忽略。

Read Committed (RC)
快照读忽略。

针对当前读,RC隔离级别保证对读取到的记录加锁 (记录锁),存在幻读现象。

Repeatable Read (RR)
快照读忽略。

针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (加 间隙锁),不存在幻读现象。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyingZCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值