MYSQL事务

MYSQL事务及MVCC

 一个不可再分的最小工作单元,通常对应一个完整的义务流程。事务是用来管理SQL的DML语句(updata、delete、insert)。

事务的四大特征ACID

  1. 原子性(Atomicity): 指一个事务的所有操作要么全部成功,要么全部失败。undo log是用来回滚数据的,用于保障未提交事务的原子性。
  2. 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
  3. 隔离性(Isolation,又称独立性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,以防止多个事务的操作导致数据的不一致。包括四种隔离级别。
  4. 持久性(Durability):指数据在任何条件下都可以写入到磁盘上。redo log是用来恢复数据的,用于保障,已提交事务的持久化特性(记录了已经提交的操作)

四种隔离级别

  1. 读未提交 read uncommitted
    事物A和事物B,事物A未提交的数据,事物B可以读取到。这种隔离级别会导致“脏读”。脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据
  2. 读已提交 read committed
    事物A和事物B,事物A提交的数据,事物B才能读取到。 这种隔离级别会导致“不可重复读取”(在事务A没有修改数据的情况下,事务A两次读取的数据不一样)。例如:事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
  3. 可重复读 repeatable read
    事务A和事务B,事务A提交之后的数据,事务B读取不到。这种隔离级别可以避免“不可重复读取”,达到可重复读取,但会导致幻读。不可重复读是读取了其他事务更改的数据,针对update操作。幻读是读取了其他事务新增的数据,针对insert与delete操作
  4. 串行化 serializable
    事务A和事务B,事务A在操作数据库时,事务B只能排队等待。这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发。一般不会使用。

MVCC(MultiVersion Concurrency Control)多版本并发控制机制

针对四钟隔离级别存在的问题(脏读、不可重复度、幻读),可以采用加锁(读锁(共享锁)、写锁(排他锁)、间隙锁)来解决,但这会影响性能。因此,采用MVCC来实现读写的并发操作(通常实现读已提交和可重复读)。InnoDB的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列, 一个保存了行的创建时间(事务ID(trx_id)),一个保存了行的过期时间(回滚指针), 当然存储的并不是实际的时间值,而是系统版本号。MVCC是通过undo log和readView来共同实现的并发控制。

  • undo log
    用于存储尚未提交的事务,即某行数据的多个版本。每个版本之间通过roll_pointer(回滚指针)连接。

  • readView :用于保存未提交的事务ID(m_ids)和已创建事务的最大事务ID (max_trx_id)。readView的作用是用于判断版本链中的哪一个版本可用,版本链包括undo log和最新的修改记录,如下图所示。版本链 undo-log
    总共4条规则来判断记录能否读取。creator_trx_id: 创建readView 的事务id、max_trx_id:以创建事务的最大ID值、min_trx_id: m_ids中最小的事务ID。

  • 四条规则如下:

  1. trx_id==creator_trx_id:可以访问这个版本,代表自己访问自己;
  2. trx_id < min_trx_id: 可以访问这个版本,代表访问已经提交的事务;
  3. trx_id > max_trx_id: 不可以访问这个版本,代表访问的事务是执行select之后创建的,不能进行访问;
  4. min_trx_id <= trx_id <= max_trx_id: 如果 trx_id 在m_ids中(代表访问的事务没有提交),则不能访问这个版本,反之可以。
  • MVCC如何实现 read committed
    每一条select 都会有一个readView。在MVCC中,一个事务开始后,每遇到一个select就会创建一个readView, 当两个select之间有新的事务提交后,通过最新的readView可以读取到已提交的数据,从而实现读已提交。
  • MVCC如何实现 reaptable read
    一个事务在执行第一条select时,会创建一个readView, 且执行之后的select时不会再创建新的readView且不会更新readView。换句话说,一个事务只在遇到第一个select才创建一个readView,且保持不变,之后的select也是使用该readView。 这样就实现了可重复读。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值