mysql给事务起名字_MySQL 事务

本文详细介绍了MySQL事务的ACID属性,包括原子性、一致性、隔离性和持久性,并讨论了事务隔离级别及其可能导致的问题。此外,还阐述了MVCC(多版本并发控制)、Gap Lock与Next-Key Lock在解决并发问题中的作用,以及redo log和undo log在事务持久性和回滚中的功能。
摘要由CSDN通过智能技术生成

事务是由一组SQL语句组成的逻辑处理单元,具有4个属性,通常简称为事务的ACID属性。

A (Atomicity) 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。使用 undo log ,从而达到回滚 C (Consistency) 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。使用 redo log,从而达到故障后恢复 I (Isolation)隔离性:一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。使用锁以及MVCC,运用的优化思想有读写分离,读读并行,读写并行 D (Durability) 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。通过回滚,以及恢复,和在并发环境下的隔离做到一致性。

没有事务隔离,可能会导入如下问题:

更新丢失(Lost Update):事务A和事务B选择同一行,然后基于最初选定的值更新该行时,由于两个事务都不知道彼此的存在,就会发生丢失更新问题

脏读(Dirty Reads):事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

不可重复读(Non-Repeatable Reads):事务 A 多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

幻读(Phantom Reads):幻读与不可重复读类似。它发生在一个事务A读取了几行数据,接着另一个并发事务B插入了一些数据时。在随后的查询中,事务A就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

事务隔离级别

SQL-92标准中定义的四种隔离级别。在MySQL中,默认的隔离级别是REPEATABLE-READ(可重复读),并且解决了幻读问题(利用Gap Locks和Next-key可以阻止其他事务在锁定区间内插入数据)。不可重复读重点在于Update和delete,而幻读的重点在于insert

读未提交:一个事务可以读取到另一个事务未提交的修改。这会带来脏读,幻读,不可重复读问题

读已提交:一个事务只能读取另一个事务已经提交的修改。其避免了脏读,仍然存在不可以重复读和幻读问题

可重复读:同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但是幻读依然存在

串行化:事务串行之行。避免了以上所有问题

【MVCC】

MVCC (MultiVersion Concurrency Control) 叫做多版本并发控制。InnoDB的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间,在实际操作中,存储的并不是时间,而是事务版本号,每开启一个新事务,事务的版本号就会递增。

b4b71d532c913f399ef14b7f4b509f70.png

增删改查中对版本号的作用如下:

select:读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本的记录。这样可以保证在读取之前记录都是存在的

insert:将当前事务的版本号保存至行的创建版本号

update:新插入一行,并以当前事务版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号

delete:将当前事务版本号保存至行的删除版本号

快照读和当前读:普通的select就是快照读,而update,delete,insert,select...LOCK In SHARE MODE,SELECT...for update就是当前读

快照读:读取的是快照版本,也就是历史版本

当前读:读取的是最新版版

afb9d61156ba6686d0dca59d381a0836.png

存在这的情况,两个事务,对同一条数据做修改。最后结果应该是哪个事务的结果呢,肯定要是时间靠后的那个,并且更新之前要先读数据,这里所说的读和上面说到的读不一样,更新之前的读叫做“当前读”,总是当前版本的数据,也就是多版本中最新一次提交的那版。

假设事务A执行 update 操作, update 的时候要对所修改的行加行锁,这个行锁会在提交之后才释放。而在事务A提交之前,事务B也想 update 这行数据,于是申请行锁,但是由于已经被事务A占有,事务B是申请不到的,此时,事务B就会一直处于等待状态,直到事务A提交,事务B才能继续执行,如果事务A的时间太长,那么事务B很有可能出现超时异常。

【Gap Lock && Next-Key Lock】

并发写问题的解决方式就是行锁,而解决幻读用的也是锁,叫做间隙锁,MySQL 把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁。

00e83cee957ff40e76238edb8af7f674.png

redo log 与 undo log

【redo log】

叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer,在内存中)以及重做日志文件(redo log,在磁盘中)。当事务提交之后会把所有修改信息都会存到该日志中。

663d7e6c534dcf6f3cd01217d95996b3.png

start transaction;

select balance from bank where name="zhangsan";

// 生成 重做日志 balance=600

update bank set balance = balance - 400;

// 生成 重做日志 amount=400

update finance set amount = amount + 400;

commit;

cad3e3642bd898196a9314340934e0c0.png

mysql 为了提升性能不会把每次的修改都实时同步到磁盘,而是会先存到Boffer Pool(缓冲池)里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。如果还没来得及同步的时候宕机或断电了,这样会导致丢部分已提交事务的修改信息!所以引入了redo log来记录已成功提交事务的修改信息,并且会把redo log持久化到磁盘,系统重启之后在读取redo log恢复最新数据。redo log是用来恢复数据的 用于保障,已提交事务的持久化特性.

【undo log】

叫做回滚日志,用于记录数据被修改前的信息。他正好跟前面所说的重做日志所记录的相反,重做日志记录数据被修改后的信息。undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。

25915f23f9e6b31b9f2844fadd850b35.png

每次写入数据或者修改数据之前都会把修改前的信息记录到 undo log。undo log 记录事务修改之前版本的数据信息,因此假如由于系统错误或者rollback操作而回滚的话可以根据undo log的信息来进行回滚到没被修改前的状态。undo log是用来回滚数据的用于保障 未提交事务的原子性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值