彻底理解数据库事务

事务

事务(Transaction),是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。例如,在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

事务和程序是两个概念。一般地讲,一个程序中包含多个事务。

事务的开始和结束可以由用户显式控制。如果用户没有显式地定义事务,则由数据库管理系统按照默认规定自动划分事务。

事务的特性

事务具有4个特性,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)持续性\永久性(Durability ),这四个特性简称为ACID特性(ACID properties)。

原子性(Atomicity):事务是数据库的罗技工作单位,事务中包括的操作要么都做,要么都不做。
一致性(Consistency):事务应确保数据库的状态从一个一致性状态转变为另一个一致性状态。一致性是通过原子性来保证的。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。接下来的其他操作或故障不应该对其执行结果有任何影响。

事务是恢复和并发控制的基本单位。保证事务ACID特性是事务管理的重要任务。事务的ACID可能遭到破坏的因素有:

(1)多个事务并行运行时,不同事务的操作交叉执行;

(2)事务在运行过程中被强行终止。

数据库管理系统中恢复机制并发控制机制的责任就是保证事务免受上述两个因素的影响。

举例

用一个常用的“A账户向B账号汇钱”的例子来说明如何通过数据库事务保证数据的准确性和完整性。熟悉关系型数据库事务的都知道从帐号A到帐号B需要6个操作:

1、从A账号中把余额读出来(500)。
2、对A账号做减法操作(500-100)。
3、把结果写回A账号中(400)。
4、从B账号中把余额读出来(500)。
5、对B账号做加法操作(500+100)。
6、把结果写回B账号中(600)。

原子性

保证1-6所有过程要么都执行,要么都不执行。一旦在执行某一步骤的过程中发生问题,就需要执行回滚操作。 假如执行到第五步的时候,B账户突然不可用(比如被注销),那么之前的所有操作都应该回滚到执行事务之前的状态。

一致性

在转账之前,A和B的账户中共有500+500=1000元钱。在转账之后,A和B的账户中共有400+600=1000元。也就是说,数据的状态在执行该事务操作之后从一个状态改变到了另外一个状态。同时一致性还能保证账户余额不会变成负数等。

隔离性

在A向B转账的整个过程中,只要事务还没有提交(commit),查询A账户和B账户的时候,两个账户里面的钱的数量都不会有变化。
如果在A给B转账的同时,有另外一个事务执行了C给B转账的操作,那么当两个事务都结束的时候,B账户里面的钱应该是A转给B的钱加上C转给B的钱再加上自己原有的钱。

持久性

一旦转账成功(事务提交),两个账户的里面的钱就会真的发生变化(会把数据写入数据库做持久化保存)!

原子性与隔离行

一致性与原子性是密切相关的,原子性的破坏可能导致数据库的不一致,数据的一致性问题并不都和原子性有关。
比如刚刚的例子,在第五步的时候,对B账户做加法时只加了50元。那么该过程可以符合原子性,但是数据的一致性就出现了问题。

因此,事务的原子性与一致性缺一不可。

My SQL事务控制语言(TCL)

当一个事务执行并完成修改时,并不是对目标表立即进行修改,此时修改的结果只是保存到临时缓存中,只有利用事务控制命令才最终认可这个事务。

控制事务的命令有3个: 
COMMIT; 
ROLLBACK; 
SAVEPOINT.

1. COMMIT命令 
COMMIT 命令用于把事务所做的修改保存到数据库,表面该事务对数据库所做的操作将永久记录到数据库。

如:删除表里所有价格低于$14的产品

DELETE FROM PRODUCT_TMP WHERE cost < 14; 
COMMIT;              /*使用COMMIT语句把修改保存到数据库,完成这个事务*/

2. ROLLBACK 命令 
ROLLBACK 命令用于撤销还没有被保存到(未提交的事务)数据库的命令,它只能用于撤销上一个COMMIT或ROLLBACK命令之后的事务。

3. SAVEPOINT命令 
保存点是事务过程中的一个逻辑点,我们可以把事务回退到这个点,而不必回退整个事务。

SAVEPOINT savepoint_name;     /*在事务语句中间创建一个保存点*/

4. ROLLBACK TO SAVEPOINT命令 
回退到保存点的命令:

ROLLBACK TO SAVEPOINT_NAME;

5.RELEASE SAVEPOINT 命令

用于删除创建的保存点,在某个保存点被释放之后,就不能再利用ROLLBACK命令来撤销这个保存点之后的事务操作了。

例:对scott.emp表综合使用COMMIT、ROLLBACK和SAVEPOINT示例。 
(1)更新scott.emp表中的sal字段,然后执行ROLLBACK操作。

UPDATE scott.emp SET sal=sal*2; /*已更新*/
ROLLBACK; /*回退已完成。(表示UPDATE语句并没有执行)*/

(2)更新scott.emp表中的sal字段,然后执行COMMIT操作。

UPDATE scott.emp SET sal=sal*2;     /*已更新*/ 
COMMIT;     /*提交完成。 (表示UPDATE真正提交到数据库)*/

(3)向表中插入员工编号为1111的记录,设置一个保存点,然后用UPDATE命令将该记录的员工姓名修改为李明,然后用ROLLBACK命令回滚到保存点。


INSERT INTO scott.emp(empno) VALUES (1111);      /*已插入一行*/
SAVEPOINT p1;     /*设置保存点p1*/ 
UPDATE scott.emp SET ename=”李明” WHERE empno=1111; 
ROLLBACK TO p1;     /*回退已完成。*/

事务控制与数据库性能 

当出现COMMIT命令时,回退事务信息被写入到目标表里,临时存储区域里的回退信息被清除; 
当出现ROLLBACK命令时,修改不会作用于数据库,而临时存储区域里的回退信息被清除; 
如果一直没有出现COMMIT 或 ROLLBACK 命令,临时存储区域里的回退信息就会不断增长,直至没有剩余空间,导致数据库停止全部进程,直至空间被释放。

猜你喜欢

转载自my.oschina.net/fairy1674/blog/1819442