事务的特性是什么?如何理解它们?

事务的特性:ACID

事务的特性:要么完全执行,要么都不执行。不过要对事务进行更深一步的理解,还要从事务的 4 个特性说起,这 4 个特性用英文字母来表达就是 ACID。

A,也就是原子性(Atomicity)。原子的概念就是不可分割,你可以把它理解为组成物质的基本单位,也是我们进行数据处理操作的基本单位。

C,就是一致性(Consistency)。一致性指的就是数据库在进行事务操作后,会由原来的一致状态,变成另一种一致的状态。也就是说当事务提交后,或者当事务发生回滚后,数据库的完整性约束不能被破坏。

I,就是隔离性(Isolation)。它指的是每个事务都是彼此独立的,不会受到其他事务的执行影响。也就是说一个事务在提交之前,对其他事务都是不可见的。

最后一个 D,指的是持久性(Durability)。事务提交之后对数据的修改是持久性的,即使在系统出故障的情况下,比如系统崩溃或者存储介质发生故障,数据的修改依然是有效的。因为当事务完成,数据库的日志就会被更新,这时可以通过日志,让系统恢复到最后一次成功的更新状态。

持久性是通过事务日志来保证的。日志包括了回滚日志和重做日志。当我们通过事务对数据进行修改的时候,首先会将数据库的变化信息记录到重做日志中,然后再对数据库中对应的行进行修改。这样做的好处是,即使数据库系统崩溃,数据库重启后也能找到没有更新到数据库系统中的重做日志,重新执行,从而使事务具有持久性。

如何对事务进行控制?控制的命令都有哪些?

  • START TRANSACTION 或者 BEGIN,作用是显式开启一个事务。
  • COMMIT:提交事务。当提交事务后,对数据库的修改是永久性的。
  • ROLLBACK 或者 ROLLBACK TO [SAVEPOINT],意为回滚事务。意思是撤销正在进行的所有没有提交的修改,或者将事务回滚到某个保存点。
  • SAVEPOINT:在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点。
  • RELEASE SAVEPOINT:删除某个保存点。
  • SET TRANSACTION,设置事务的隔离级别。

为什么我们执行 COMMIT、ROLLBACK 这些命令的时候,有时会成功,有时会失败?

在使用事务的过程中,我们会采用控制流语句对事务进行操作,不过在实际操作中,不一定每次使用 COMMIT 或 ROLLBACK 都会成功,你还需要知道当前系统的事务执行方式,也就是一些常用的参数情况,比如 MySQL 中的 autocommit 和 completion_type 等。

使用事务有两种方式,分别为隐式事务和显式事务。隐式事务实际上就是自动提交,Oracle 默认不自动提交,需要手写 COMMIT 命令,而 MySQL 默认自动提交,当然我们可以配置 MySQL 的参数:

mysql> set autocommit =0;  // 关闭自动提交
mysql> set autocommit =1;  // 开启自动提交

当然也可以设置 completion_type :

SET @@completion_type = 1;

MySQL 中 completion_type 参数有 3 种可能:

  • completion=0,这是默认情况。也就是说当我们执行 COMMIT 的时候会提交事务,在执行下一个事务时,还需要我们使用 START TRANSACTION 或者 BEGIN 来开启。
  • completion=1,这种情况下,当我们提交事务后,相当于执行了 COMMIT AND CHAIN,也就是开启一个链式事务,即当我们提交事务之后会开启一个相同隔离级别的事务(隔离级别会在下一节中进行介绍)。
  • completion=2,这种情况下 COMMIT=COMMIT AND RELEASE,也就是当我们提交后,会自动与服务器断开连接。

当我们设置 autocommit=0 时,不论是否采用 START TRANSACTION 或者 BEGIN 的方式来开启事务,都需要用 COMMIT 进行提交,让事务生效,使用 ROLLBACK 对事务进行回滚。

当我们设置 autocommit=1 时,每条 SQL 语句都会自动进行提交。 不过这时,如果你采用 START TRANSACTION 或者 BEGIN 的方式来显式地开启事务,那么这个事务只有在 COMMIT 时才会生效,在 ROLLBACK 时才会回滚。