数据库事务

来源:互联网 发布:农村淘宝 app 下载 编辑:程序博客网 时间:2024/06/05 23:59

博文来源属于截取书上的内容,书是向朋友借来的,我就是记录一下内容。内容属于基础。

事务

学习重点
① 事务是需要在同一个处理单元中执行的一系列更新处理的集合。通过使用事务,可以对数据库中的数据更新处理的提交和取消进行管理。
② 事务处理的终止指令包括COMMIT(提交处理)和ROLLBACK(取消处理)两种。
③ DBMS(数据库管理系统)的事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)四种特性。通常将这四种特性的首字母结合起来,统称为ACID特性。

什么是事务?
估计有些读者对事务(Transaction)这个词并不熟悉。它通常都带有一些商务贸易或者经济活动的意味。但是在RDBMS(关系数据库管理系统)中,事务代表了对表中数据进行更新的单位。简单来讲,事务就是需要在同一个处理单元中执行的一系列更新处理的集合
我们对表进行更新需要使用INSERT、DELETE或者UPDATE三种语句。但通常情况下,更新处理并不是执行一次就结束了,而是需要执行一系列连续的操作。这时,事务就能体现出它的价值了。

比如我们现在一张表(Shohin_01)

CREATE TABLE Shohin_01(   shohin_id  CHAR(4) NOT NULL,   shoin_mei varchar2(100) NOT NULL,   shoin_bunrui Varchar2(32) NOT NULL,   hanbai_tanka INTEGER,   shiire_tanka integer,   torokubi DATE,   PRIMARY KEY(shohin_id));

添加一组数据

INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘001’,’T恤衫’,’衣服’,1000,500,to_date(‘2009-09-20’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘002’,’打孔器’,’办公用品’,500,320,to_date(‘2009-09-11’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘003’,’运动T恤’,’衣服’,4000,2800,null);
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘004’,’菜刀’,’厨房用具’,3000,2800,to_date(‘2009-09-20’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘005’,’高压锅’,’厨房用具’,6800,5000,to_date(‘2009-01-15’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘006’,’叉子’,’厨房用具’,500,null,to_date(‘2009-09-20’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘007’,’擦菜板’,’厨房用具’,880,790,to_date(‘2008-04-28’,’yyyy-mm-dd’));
INSERT INTO Shohin_01(shohin_id,shoin_mei,shoin_bunrui,Hanbai_Tanka,Shiire_Tanka,torokubi) VALUES(‘008’,’圆珠笔’,’办公用品’,100,NULL,to_date(‘2009-11-11’,’yyyy-mm-dd’));

备注:

商品表中的列名            shohin表定义的列名    商品编号                 shohin_id    商品名称                 shohin_mei    商品分类                 shohin_bunrui    销售单价                 hanbai_tanka    进货单价                 Shiire_Tanka    登记日期                 torokubi

销售部门的领导对你提出了如下要求:

“经过会议讨论,我们决定把运动T恤的销售单价下调1000元,同时把T恤的销售单价上浮1000元,麻烦你去更新一下数据库”

现在大家都想到办法了——只需要使用UPDATE进行更新就可以了,所以肯定会直接回答“知道了,请您放心吧”。
此时的事务就是由如下两条更新处理所组成。

①将运动T恤的销售单价降低1000元。
UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka - 1000 WHERE h.shoin_mei = ‘运动T恤’;
②将T恤的销售单价上浮1000元。
UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka + 1000 WHERE h.shoin_mei = ‘T恤衫’;

上诉①和②的操作一定要作为同一个处理单元执行。如果只执行了①的操作而忘记了执行②的操作,或者反过来只执行了②的操作而忘记了执行① 的操作,一定会受到领导的严厉批评。遇到这种需要在同一个处理单元中执行一系列更新操作的情况,一定要使用事务来进行处理。

法则    事务是需要在同一个处理单元中执行的一系列更新处理的集合。

一个事务中包含多少个更新处理或者包含哪些处理,在DBMS中并没有固定的标准。而是根据用户的要求决定的(例如,运行T恤和T恤的销售单价需要同时更新这样的要求,DBMS是无法了解的)。

创建事务

如果想在DBMS中创建事务,可以按照如下的语法结构编写SQL语句。

 事务开始语句;     DML语句①;     DML语句②;     DML语句③;     .     .     .事务结束语句(COMMIT或者ROLLBACK);

使用事务开始语句和事务结束语句,将一系列DML语句(INSERT/UPDATE/DELETE语句)括起来,就实现了一个事务处理。
这时需要特别注意的是事务的开始语句(与之相对,事务结束语句只有COMMIT和ROLLBACK两种,在所以的RDBMS中都有通用的)。实际上,在标准SQL中并没有定义事务的开始语句,而是由各个DBMS自己来定义的,比较有代表的语法如下所示。

◆ SQL Server、Postgre SQL    BEGIN TRANSACTION◆ MySQL    START TRANSACTION◆ Oracle、DB2    无

例如使用之前的那两个UPDATE(①和②)创建出的事务如代码清单如下所示。

◆ SQL Server、Postgre SQL    BEGIN TRANSACTION;    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka - 1000 WHERE h.shoin_mei = '运动T恤';    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka + 1000 WHERE h.shoin_mei = 'T恤衫';    COMMIT;◆ MySQL    START TRANSACTION;    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka - 1000 WHERE h.shoin_mei = '运动T恤';    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka + 1000 WHERE h.shoin_mei = 'T恤衫';    COMMIT;◆ Oracle、DB2    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka - 1000 WHERE h.shoin_mei = '运动T恤';    UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka + 1000 WHERE h.shoin_mei = 'T恤衫';    COMMIT;

如上所示,各个DNMS事务的开始语句都不尽相同。其中Oracle和DB2并没有定义特定的开始语句。
反之,事务的结束需要用户明确地给出提示。事务结束的指令有如下两种。

● COMMIT——提交处理

commit是提交事务包含的全部更新处理的结束指令,相当于文件处理中的覆盖保存。一旦提交,就无法恢复到事务开始前的状态了,因此,在提交之前一定要确认是否真的需要进行这些更新。

    结束后的状态:②中的所有更新都被反映到了数据库中

万一由于误操作提交了包含错误更新的事务,就只能重新回到重新建表、重新插入数据这样繁琐的老路中。由于可能会造成数据无法恢复的后果,请初学者一定要注意(特别是在执行DELETE语句的COMMIT时尤其要小心)。

虽然我们可以不清楚事务开始的时点,但是在事务结束时一定要仔细进行确认。

下一个。。。

● ROLLBACK——取消处理

ROLLBACK是取消事务包含的全部更新处理的结束指令。相当于文件处理中的放弃保存。一旦回滚,数据库就会回复到事务开始之前的状态。通常回滚并不会像提交那样造成大规模的数据损失。

结束后的状态:和①执行前相同。

事务回滚的例子

    ◆ SQL Server、Postgre SQL        BEGIN TRANSACTION;        UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka - 1000 WHERE h.shoin_mei = '运动T恤';        UPDATE Shohin_01 h SET h.hanbai_tanka = h.hanbai_tanka + 1000 WHERE h.shoin_mei = 'T恤衫';        ROLLBACK;

上诉事务处理执行之后,表中的数据不会发生任何改变。这是因为执行最后一行的ROLLBACK之后,所有的处理都被取消了。因此,回滚执行起来就无需像提交时那样小心翼翼了(即使是想要提交的情况,也只需要重新执行事务处理就可以了)。

ACID特性
DBMS的事务都遵循四种标准规格的约定。将这四种特性的首字母结合起来统称为ACID特性。这些约定是所有DBMS都必须遵守的规则。

■ 原子性(Atomicity)

原子性是指在事务结束时,其中所包含的更新处理要么全部执行,要么完全不执行的特性。也就是要么占有一切要么一无所有。例如,在之前的例子中,事务结束时,是绝对不可能出现运动T恤的价格下降了,而T恤的价格却没有上涨的情况。该事务的结束状态,要么是两者都执行了(COMMIT),要么是两者都未执行(ROLLBACK)。
从事务中途停止的角度去考虑,就能比较容易理解原子性的重要性了,由于用户在一个事务中定义了两条UPDATE语句,DBMS肯定不会只执行其中一条,否则就会对业务处理造成影响。

■ 一致性(Consistency)

一致性指的是事务中包含的处理,要满足数据库提前设置的约束,如主键约束或者NOT NULL约束等。例如,设置了NOT NULL约束的列是不能更新为NULL的,试图插入违反主键约束的记录就会出错,无法执行。对事物来说,这些不合法的SQL会被回滚。也就是说这些SQL处理会被取消,不会执行。
一致性也称为完整性。
保持完成性的流程

结束后的状态:只有②-2的更新没有被反映到数据库中。违反约束。

■ 隔离性(Isolation)

隔离性指的是保证不同事务之间互不干扰的特性。该特性保证了事务之间不会互相嵌套。此外,在某个事务中进行的更改,在该事务结束之前,对其他事务而言是不可见的。因此,即使某个事务向表中添加了记录,在没有提交之前,其他事务是看不到新添加的记录的。

■ 持久性(Durability)

持久性也可以称为耐久性,指的是事务(不论是提交还是回滚)一旦结束,DBMS会保证该时点的数据状态得以保存的特性。即使由于系统故障导致数据丢失,数据库也一定能通过某种手段进行恢复。
如果不能保证持久性,即使是正常提交结束的事务,一旦发生了系统故障,就会导致数据丢失,一切都需要从头再来的后果。
保证持久性的方法根据实现的不同而不同,其中最常见的就是将事务的执行记录保存到硬盘等存储介质中(该执行记录称为日志)。当发生故障时,可以通过日志恢复到故障发生前的状态。

1 0
原创粉丝点击