数据库事务简介.

1、事务分类

事务是访问并更新数据库中各类数据项的一个程序执行单元,事务会把数据库从一种一致状态转换为另外一种一致状态,这就是事务的目的,也是事务模型区别与文件系统的重要特性之一。html

InnoDB 存储引擎中的事务(READ REPEATABLE 隔离级别)彻底符合 ACID 的特性。ACID 是如下 4 个词的缩写:mysql

  • 原子性(atomicity):数据库事务是不可分割的工做单位,事务中的数据库操做要么都成功,要么都不成功。
  • 一致性(consistency):将数据库从一种状态转变为下一种一致的状态,在事务开始以前和事务结束之后,数据库的完整性约束没有被破坏。
  • 隔离性(isolation):每一个读写事务的对象对其余事务的操做对象能相互分离,即该事务提交前对其余事务都不可见,一般这使用锁来实现。
  • 持久性(durability):事务一旦提交,其结果就是永久性的。

从事务理论的角度来讲,能够把事务分为如下几种类型:sql

  • 扁平事务(Flat Transactions)
  • 带有保存点的扁平事务(Flat Transactions with Savepoints)
  • 链事务(Chained Transactions)
  • 嵌套事务(Nested Transactions)
  • 分布式事务(Distributed Transactions)

1. 扁平事务(Flat Transactions)

最简单,使用最频繁的事务,其间的操做是原子的,要么都执行,要么都回滚,也就是一般意义上咱们理解的事务概念。数据库

2. 带有保存点的扁平事务(Flat Transactions with Savepoints)

容许在事务执行过程当中回滚到同一事务中较早的一个状态,保存点(Savepoint)用来通知系统应该记住事务当前的状态,以便当以后发生错误时,事务能回到保存点当时的状态。
缓存

3. 链事务(Chained Transactions)

在提交一个事务时,释放不须要的数据对象,将必要的处理上下文隐式地传给下一个要开始的事务,这意味着下一个事务将看到上一个事务的结果,就好像在一个事务中进行的同样。
架构

4. 嵌套事务(Nested Transactions)

由一个顶层事务(top-level transaction)控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务(subtransaction),其控制每个局部的变换。Moss 对嵌套事务这样描述:
1)嵌套事务是由若干事务组成的一颗树,子树既能够是嵌套事务,也能够是扁平事务。并发

2)处在叶节点的事务是扁平事务,可是每一个子事务从跟到叶节点的距离能够是不一样的。分布式

3)位于根节点的事务称为顶层事务,其余事务称为子事务,事务的前驱称为父事务(parent),事务的下一层称为儿子事务(child)。ide

4)子事务既能够提交也能够回滚,可是它的提交操做并不会立刻生效,除非其父事务已经提交。高并发

5)树中的任意一个事务的回滚会引发它的全部子事务一同回滚,故子事务仅保留 A、C、I 特性,不具备 D 的特性。

5. 分布式事务(Distributed Transactions)

分布式事务指的是容许多个独立的事务资源(transactional resources)参与到一个全局的事务中,全局事务要求在其中的全部参与的事务要么都提交,要么都回滚。

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

2、事务控制语句

在 MySQL 命令行的默认设置下,事务都是自动提交(auto commit)的,即执行 SQL 语句后就会立刻执行 COMMIT 操做。所以要显示的控制一个事务,就要用到事务控制语句。

  • START TRANSACTION | BEGIN :显式地的开启一个事务;
  • COMMIT | COMMIT WORK:提交事务,并使得已对数据库作的全部修改为为永久性的;
  • ROLLBACK | ROLLBACK WORK:回滚用户的事务并撤销正在进行的全部未提交的事务;
  • SAVEPOINT [identifier]:建立一个保存点,一个事务中能够有多个 SAVEPOINT;
  • ROLLBACK TO [SAVEPOINT]:把事务回滚到标记点,而不回滚在此标记点以前的任何工做;
  • SET TRANSACTION:用来设置事务的隔离级别;

COMMIT 和 COMMIT WORK 语句基本上是一致的,都是用来提交事务,不一样之处在于 COMMIT WORK 用来控制事务结束后的行为是 CHAIN 仍是 RELEASE 的,该行为受 completion_type 参数控制。

SHOW VARIABLES LIKE '%completion_type%';

如下这些 SQL 语句会产生一个隐式的提交操做,即执行完这些语句后,会有一个隐式的 COMMIT 操做,即这些 SQL 语句执行完是不能被回滚的。

  • DDL 语句;
  • 管理语句:ANALYZE TABLE、CACHE INDEX、CHECK TABLE、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE;
  • 隐式修改 MySQL 架构的操做:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD;

3、事务隔离级别

ISO 和 ANIS SQL 标准制定了四种事务隔离级别的标准,分别为:

  • Read Uncommitted 读未提交
  • Read Committed 读已提交
  • Repeatable Read 可重复读
  • Serializable 串行化

有关事务隔离级别的内容在 InnoDB 存储引擎中的锁 有讲解,可参考。

在 INNODB 存储引擎中,可使用如下命令来设置当前会话或全局的事务隔离级别:

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]

据了解,大部分的用户质疑 Serializable 隔离级别带来的性能问题,可是根据 Jim Gray 在 《Transaction Processing》一书中指出,二者的开销几乎是同样的,甚至 Serializable 可能更优!!!所以在 InnoDB 存储引擎中选择 Repeatable Read 的事务隔离级别并不会有任何性能的损失。一样地,即便使用 Read Committed 的隔离级别,用户也不会获得性能的大幅度提高。

在 SERIALIZABLE 的事务隔离级别下,INNODB 存储引擎会对每一个 SELECT 语句后自动加上 LOCK IN SHARE MODE,即为每一个读取操做加一个共享锁。

4、分布式事务

XA(eXtended Architecture)是指由 X/Open 组织提出的分布式交易处理的规范。XA 是一个分布式事务协议,由Tuxedo 提出,因此分布式事务也称为 XA 事务。

XA 协议主要定义了事务管理器 TM(Transaction Manager,协调者)和资源管理器 RM(Resource Manager,参与者)之间的接口。其中,资源管理器每每由数据库实现,如 Oracle、DB二、MySQL,这些商业数据库都实现了 XA 接口,而事务管理器做为全局的调度者,负责各个本地资源的提交和回滚。

XA 事务是基于两阶段提交(Two-phaseCommit,2PC)协议实现的,能够保证数据的强一致性,许多分布式关系型数据管理系统都采用此协议来完成分布式。阶段一为准备阶段,即全部的参与者准备执行事务并锁住须要的资源。当参与者 Ready 时,向 TM 汇报本身已经准备好。阶段二为提交阶段。当 TM 确认全部参与者都 Ready 后,向全部参与者发送 COMMIT 命令。

XA 事务由一个或多个资源管理器(RM)、一个事务管理器(TM)和一个应用程序(ApplicationProgram)组成。

XA 事务的缺点是性能很差,且没法知足高并发场景。一个数据库的事务和多个数据库间的 XA 事务性能会相差不少。所以,要尽可能避免 XA 事务,如能够将数据写入本地,用高性能的消息系统分发数据,或使用数据库复制等技术,只有在其余办法都没法实现业务需求,且性能不是瓶颈时才使用 XA。

SHOW VARIABLES LIKE 'innodb_support_xa';

5、其它

  1. redo log 称为重作日志,恢复提交事务修改的页操做,用来保证事务的原子性和持久性;undo log 称为回滚日志,帮助回滚行记录到某个特定版本及 MVCC 的功能,用来保证事务的一致性;

  2. 参数 innodb_flush_log_at_trx_commit 用来控制重作日志刷新到磁盘的策略。该参数的默认值为 1,表示事务提交时必须调用一次 fsync 操做刷新到磁盘;0 表示事务提交时不进行重作日志刷新到磁盘操做,该操做仅在 master thread 中完成(mysql 宕机,未刷新到磁盘的数据会所有丢失);2 表示事务提交时,仅将重作日志写入文件系统的缓存中,不进行 fsync 操做(只要操做系统不宕机,数据就不会丢);

  3. 磁盘的 fsync 性能是有限的,为了提升磁盘 fsync 的效率,当前数据库都提供了 group commit 的功能,即一次 fsync 能够刷新确保多个事务日志被写入文件;

  4. 用户一般对 undo 有这样误解:undo 用于将数据库物理地恢复到执行语句或事务以前的样子 —— 但事实并不是如此,undo 是逻辑日志,所以只是将数据库逻辑地恢复到原来的样子;

  5. 最多见的 MySQL 内部的 XA 事务存在于 binlog 与 InnoDB 存储引擎之间,对于 binlog 日志和 InnoDB 存储引擎的 REDO 日志,必须同时写入,其就是用 XA 事务来保障的;

  6. 不要在循环中提交事务,而应该把循环当成一个事务;

  7. 长事务[Long-Lived Trascactions] 指的是执行时间较长的事务,对于长事务的问题,有时能够经过转化为小批量(mini batch)的事务来进行处理。

相关文章
相关标签/搜索