事务的概念
数据库把需要保证原子性、隔离性、一致性和持久性的一个或多个数据库操作称为事务 (transcation)。
数据库世界只是现实世界的一个映射,事务的原子性、隔离性、一致性和持久性就是现实世界中状态转换的规则。
原子性(Atomicity)
在现实世界中,转账操作是一个不可分割的操作。「要么全做,要么全不做」的规则称为原子性。
隔离性(Isolation)
对于现实世界中状态转换对应的某些数据库操作来说,不仅要保证这些操作以原子 性的方式执行完成,而且要保证其他的状态转换不会影响到本次状态转换,这个规则称为隔离性。
一致性(Consistenty)
如果数据库中的数据全部符合现实世界中的约束,我们就说这些数据就是一致的,或者说符合一致性的。
持久性(Durability)
当现实世界中的一个状态转换完成后,这个转换的结果将永久保留,这个规则被称为持久性。
事务的状态
事务是一个抽象的概念 , 它其实对应着一个或多个数据库操作。数据库根据这些操作所执行的不同阶段把事务大致划分成了下面几个状态:
- 活动的(active):事务对应的数据库操作正在执行过程中时,我们就说该事务处于活动的状态。
- 部分提交的 (partiaIly committed):当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并没有刷新到磁盘时,我们就说该事务处于部分提交的状态。
- 失败的(failed):当事务处于活动的状态或者部分提交的状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行, 或者人为停止了当前事务的执行,我们就说该事务处于失败的状态。
- 中止的 (aborted):如果事务执行了半截而变为失败的状态,那么就需要撤销失败事务对当前数据库造成的影响。这个撤销的过程用书面一点的话描述就是:回滚。当回滚操作执行完毕后,也就是数据库恢复到了执行事务之前的状态,我们就说该事务处于中止的状态。
- 提交的 (committed):当一个处于部分提交的状态的事务将修改过的数据都刷新到磁盘中之后,我们就可以说该事务处于提交的状态。
事务的状态转换
只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束了。对于已经提交的事务来说,该事务对数据库所做的修改将永久生效;对于处于中止状态的事务来说,该事务对数据库所做的所有修改都会被回滚到没执行该事务之前的状态。
支持事务的存储引擎
在 MySQL 中,并不是所有的存储引擎都支持事务的功能,目前只有 InnoDB 和 NDB 存储引擎支持。如果某个事务中包含的语句要修改某个表中的数据,但是该表使用的存储引擎不支持事务,那么对该表所做的修改将无法进行回滚。
自动提交
MySQL 中有一个系统变量 autocommit , 用来自动提交事务。它的默认值为 ON 也就是说在默认情况下,如果不显式地使用 START TRANSCATION 或者 BEGIN 语句开启一个事务,那么每一条语句都算是一个独立的事务,这种特性称为事务的自动提交。
关闭自动提交
- 显式地使用 START TRANSCATION 或者 BEGIN 语句开启一个事务。这样在本次事务提交或者回滚前会暂时关闭自动提交的功能。
把系统变量 autocommit 的值设置为 OFF,如下所示:
SET autocommit = OFF;
这样一来,我们写入的多条语句就算是属于同一个事务了,直到我们显式地写出 COMMIT 语句把这个事务提交掉;或者显式地写出 ROLLBACK 语句把这个事务回滚掉。
隐式提交
如果我们输入了某些语句,且这些语句会导致之前的事务悄悄地提交掉(就像输入了 COMMIT 语句了一样) 。那么这种因为某些特殊的语句而导致事务提交的情况称为隐式提交。会导致事务隐式提交的语句有下面这些:
定义或修改数据库对象的数据定义语言(Data Definition Language,[[DDL]])。
- 所谓的数据库对象,指的就是数据库、表、视图、存储过程等这些东西。当使用 CREATE、ALTER、DROP 等语句修改这些数据库对象时,就会隐式地提交前面语句所属的事务。
隐式使用或修改 mysql 数据库中的表。
- 在使用 ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、 REVOKE、SET PASSWORD 等语句时,也会隐式地提交前面语句所属的事务。
事务控制或关于锁定的语句。
- 当我们在一个事务还没提交或者还没回滚时就又使用 START TRANSACTION 或者 BEGIN 语句开启了另一个事务,此时会隐式地提交上一个事务。
- 在当前的 autocommit 系统变量的值为 OFF,而我们手动把它调为 ON 时,也会隐式地提交前面语句所属的事务。
- 使用 LOCK TABLES、UNLOCK TABLES 等关于锁定的语句也会隐式地提交前面语句所属的事务。
加载数据的语句。
- 比如使用 LOAD DATA 语句向数据库中批量导入数据时,也会隐式地提交前面语句所属的事务。
关于 MySQL 复制的一些语句 。
- 使用 START SLAVE、STOP SLAVE、RESET SLAVE、CHANGE MASTER TO 等语句时也会隐式地提交前面语句所属的事务。
其他语句.
- 使用 ANALYZE TABLE、CACHE INDEX 、CHECK TABLE、FLUSH、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE、RESET 等语句时也会隐式地提交前面语句所属的事务。