Mysql进阶-InnoDB事务

文章目录

  • 一、为什么要有事务?
  • 二、ACID属性
  • 三、事务的实现
    • 1. redo
    • 2. undo
  • 四、事务隔离级别
  • 五、分布式事务

一、为什么要有事务?

事务会把数据库从一种一致状态转换为另一种一致状态。在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所有修改都不保存。

二、ACID属性

字母 属性 介绍
A(Atomicity) 原子性 原子性指整个数据库事务是不可分割的工作单位。只有使事务中所有的数据库操作都执行成功,才算整个事务成功。事务中任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。
C(consistency) 一致性 一致性指事务将数据库从一种状态转变为下一种一致的状态。在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
I(isolation) 隔离性 事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常这使用锁来实现。
D(durability) 持久性 事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能将数据恢复。

持久性保证事务系统的高可靠性(High Reliability),而不是高可用性(High Availability)。对于高可用性的实现,事务本身并不能保证,需要一些系统共同配合来完成。

三、事务的实现

事务隔离性锁来实现。原子性、一致性、持久性通过数据库的redolog和undo log来完成。redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。

redo恢复提交事务修改的页操作,而undo回滚行记录到某个特定版本。
redo通常是物理日志,记录的是页的物理修改操作。undo是逻辑日志,根据每行记录进行记录。
redo log用来保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能。
redo log基本上都是顺序写的,在数据库运行时不需要对redo log的文件进行读取操作。而undolog是需要进行随机读写的。

1. redo

重做日志用来实现事务的持久性,即事务ACID中的D。其由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其是易失的;二是重做日志文件(redolog file),其是持久的。

当事务提交(COMMIT)时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的COMMIT操作完成才算完成。

binlog 与redolog的不同点:
重做日志是在InnoDB存储引擎层产生,而二进制日志是在MySQL数据库的上层产生的
MySQL数据库上层的二进制日志是一种逻辑日志,其记录的是对应的SQL语句。而InnoDB存储引擎层面的重做日志是物理格式日志,其记录的是对于每个页的修改。
两种日志记录写入磁盘的时间点不同。二进制日志只在事务提交完成后进行一次写入。InnoDB存储引擎的重做日志在事务进行中不断地被写入,这表现为日志并不是随事务提交的顺序进行写入的。

2. undo

事务有时还需要进行回滚操作,这时就需要undo。因此在对数据库进行修改时,InnoDB存储引擎不但会产生redo,还会产生一定量的undo。

InnoDB存储引擎自身也对恢复进行了一定程度的优化,如顺序读取及并行应用重做日志,这样可以进一步地提高数据库恢复的速度。

如果用户执行的事务或语句由于某种原因失败了,又或者用户用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据回滚到修改之前的样子。

undo的另一个作用是MVCC,即在InnoDB存储引擎中MVCC的实现是通过undo来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。

四、事务隔离级别

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

InnoDB存储引擎默认支持的隔离级别是REPEATABLE READ,但是与标准SQL不同的是,InnoDB存储引擎在REPEATABLE READ事务隔离级别下,使用Next-KeyLock锁的算法,因此避免幻读的产生。

隔离级别越低,事务请求的锁越少或保持锁的时间就越短。

在SERIALIABLE的事务隔离级别,InnoDB存储引擎会对每个SELECT语句后自动加上LOCK IN SHARE MODE,即为每个读取操作加一个共享锁。因此在这个事务隔离级别下,读占用了锁,对一致性的非锁定读不再予以支持。

在READ COMMITTED的事务隔离级别下,除了唯一性的约束检查及外键约束的检查需要gap lock,但是InnoDB存储引擎不会使用gap lock的锁算法。

五、分布式事务

分布式事务指的是允许多个独立的事务资源(transactional resources)参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对于事务原有的ACID要求又有了提高。

InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。

另外,在使用分布式事务时,InnoDB存储引擎的事务隔离级别必须设置为SERIALIZABLE。

分布式事务使用两段式提交(two-phase commit)的方式。在第一阶段,所有参与全局事务的节点都开始准备(PREPARE),告诉事务管理器它们准备好提交了。在第二阶段,事务管理器告诉资源管理器执行ROLLBACK还是COMMIT。如果任何一个节点显示不能提交,则所有的节点都被告知需要回滚。

使用事务的坏习惯:

  1. 在循环中提交事务
  2. 使用自动提交
  3. 使用自动回滚
  4. 长事务

你可能感兴趣的:(mysql,mysql)