13.7 事务处理 13.7.1 事务的概念和MySQL事务支持
13.7 事务处理
对于任何数据库应用而言,事务都是非常重要的,事务是保证底层数据完整的重要手段,没有事务支持的数据库应用,那将非常脆弱
13.7.1 事务的概念和MySQL事务支持
事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。
程序和事务是两个不同的概念。一般而言,一段程序中可能包含多个事务。
事务的4个特性
事务具备4个特性:
- 原子性(
Atomicity), - 一致性(
Consistency), - 隔离性(
Isolation), - 持续性(
Durability)。
这4个特性也简称为ACID性
原子性
原子性( Atomicity):事务是应用中最小的执行单位,事务是应用中不可再分的最小逻辑执行体。
一致性
一致性( Consistency):事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中断,而该未完成的事务对数据库所做的修改已被写入数据库此时,数据库就处于一种不正确的状态。比如银行在两个账户之间转账:从A账户向B账户转入1000元,系统先减少A账户的1000元,然后再为B账户增加1000元。如果全部执行成功,数据库处于一致性状态;如果仅减少A账户金额,而没有增加B账户的金额,则数据库就处于不一致性状态;因此,一致性是通过原子性来保证的。
隔离性
隔离性( Isolation):各个事务的执行互不干扰,任意一个事务的内部操作对其他并发的事务都是隔离的。也就是说,并发执行的事务之间不能看到对方的中间状态,并发执行的事务之间不能互相影响。
持续性
持续性( Durability):持续性也称为持久性( Persistence),指事务一旦提交,对数据所做的任何改变都要记录到永久存储器中,通常就是保存进物理数据库。
事务语句组成
数据库的事务由下列语句组成。
- 一组
DML语句,经过这组DML语句修改后的数据将保持较好的一致性。(DML指的是:insert,update,delete这三条SQL语句) - 一条
DDL语句。(DDL指的是create,alter,drop,truncate等语句) - 一条
DCL语句。(DCL指的是:grant等语句)
注意
事务中的DDL和DCL语句最多只能有一条,因为DDL和DCL语句都会导致事务立即提交。
提交
当事务所包含的全部数据库操作都成功执行后,应该提交( commit)事务,使这些修改永久生效。
事务提交有两种方式:显式提交和自动提交。
- 显式提交:使用
commit时. - 自动提交:执行
DDL或DCL语句,或者程序正常退出时。
回滚
当事务所包含的任意一个数据库操作执行失败后,应该回滚(rollback)事务,使该事务中所做的修改全部失效。事务回滚有两种方式:显式回滚和自动回滚。
- 显式回滚:使用
rollback。 - 自动回滚:系统错误或者强行退出。
如何开启 关闭事务
MySQL默认关闭事务(即打开自动提交),在默认情况下,用户在MySQL控制台输入一条DML语句,这条DML语句将会立即保存到数据库里。为了开启MySQL的事务支持,可以显式调用如下命令:
1 | SET AUTOCOMMIT={0|1} #0为关闭自动提交,即开启事务 |
注意:自动提交和开启事务恰好相反,如果开启自动提交就是关闭事务;关闭自动提交就是开启事务。
临时开启事务
除此之外,如果不想关闭整个命令行窗口的自动提交,而只是想临时性地开始事务,则可以使用MySQL提供的start transaction或begin两个命令,它们都表示临时性地开始一次事务,处于starttransaction或begin后的DML语句不会立即生效,除非使用commit显式提交事务,或者执行DDL、DCL语者来隐式提交事务。如下SQL代码将不会对数据库有任何影响。
1 | begin; |
执行上面SQL语句中的第①条查询语句将会看到刚刚插入的3条记录,如果打开MySQL的其他命令行窗口将看不到这3条记录—这正体现了事务的隔离性。
接着程序rollback了事务中的全部修改,执行第②条查询语句时将看到数据库又恢复到事务开始前的状态。
对于提交,不管是显式提交还是隐式提交,都会结束当前事务;
对于回滚,不管是显式回滚还是隐式回滚,都会结束当前事务。
保存点
除此之外, MySQL还提供了savepoint来设置事务的中间点,通过使用savepoint设置事务的中间点可以让事务回滚到指定中间点,而不是回滚全部事务。如下SQL语句设置了一个中间点:
1 | savepoint a; |
一旦设置了中间点后,就可以使用rollback回滚到指定中间点,回滚到指定中间点的代码如下:
1 | rollback to a; |
注意:
普通的提交、回滚都会结束当前事务,
但回滚到指定中间点因为依然处于事务之中,所以不会结束当前事务.