20 管理事务处理

1.事务处理

通过事务处理,通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。

事务处理是一种机制,用来管理必须成批执行的SQL操作,保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组操作不会中途停止,它们要么完全执行,要么完全不执行。如果没有错误发生,整组语句提交给数据库表;如果发生错误,则进行回退,将数据库恢复到某个已知且安全的状态。

假设订单存储在Orders和OrderItems表中,Orders存储实际的订单,OrderItems存储订购的各项物品。这两个表使用称为主键的唯一ID互相关联,又与包含客户和产品信息的其他表相关联。

给系统添加订单的过程如下:

(1)检查数据可中是否存在相应的顾客,若不存在则添加该顾客;

(2)检索顾客的ID;

(3)在Orders表添加一行,它与顾客ID相关联;

(4)检索Order表中赋予的新订单ID;

(5)为订购的每个物品在OrderItems表中添加一行,通过检索出来的ID把它与Orders表以及Products表关联。

假设由于某种数据库故障,该过程无法完成。

若故障发生在添加顾客之后,添加Orders表之前,则不会有问题。可以有效地从出故障的地方开始执行此过程。

若故障发生在插入Orders行之后,添加OrderItems行之前。这样数据库有一个空订单。

而若系统在添加OrderItems行之时出现故障,这时数据库将存在未知的不完整的订单,这样更糟糕。此时需要使用事务处理。

该工作过程如下:

(1)检查数据可中是否存在相应的顾客,若不存在则添加该顾客;

(2)提交顾客信息;

(3)检索顾客的ID;

(4)在Orders表添加一行;

(5)若向Orders表添加行时出现故障,回退;

(6)检索Order表中赋予的新订单ID;

(7)对于订购的每项物品,添加新行到OrderItems表;

(8)若向OrderItems添加行时出现故障,回退所有添加的OrderItems行和Orders行。

几个术语:

  • 事务:一组SQL语句;
  • 回退:撤销指定SQL语句;
  • 提交:将未存储的SQL语句结果写入数据库表;
  • 保留点:事务处理中设置的临时占位符,可以对它发布回退。

可回退:INSERT、UPDATE、DELETE语句;

不可回退:SELECT(也没必要)、CREATE、DROP操作。

 

2.控制事务处理

管理事务的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。

有的DBMS要求明确标识事务处理块的开始或结束。

MySQL中的标识,输入:

START TRANSACTION

...

多数实现没有明确表示事务处理在何处结束,事务一直存在,直到被中断。通常,COMMIT用于保存更改,ROLLBACK用于撤销。

(1)使用ROLLBACK

SQL的ROLLBACK命令用来回退SQL语句。

输入:

DELETE FROM Orders;

ROLLBACK;

(2)使用COMMIT

使用COMMIT语句进行明确的提交。

一个SQL Server列子,输入:

BEGAIN TRANSACTION

DELETE OrderItems WHERE order_num = 12345

DELETE Orders WHERE order_num = 12345

COMMIT TRANSACTION

(3)使用保留点

要支持回退部分事务,必须在事务处理块中的合适位置放置占位符。SQL中,这些占位符称为保留点。

MySQL中,可以使用SAVEPOINT语句。

输入:

SAVEPOINT delete1;

每个保留点具有能够标识它的唯一名字,以便在回退时,DBMS知道回退到何处。MySQL中,要回退到该保留点,可以输入:

ROLLBACK TO delete1;

一个完整的SQLServer例子:

BEGIN TRANSACTION

INSERT INTO Customers(cust_id, cust_name)

VALUES('1000000010', 'Toys Emporium');

SAVE TRANSACTION StartOrder;

INSERT INTO Orders(order_num, order_date, cust_id)

VALUES(20100,'2001/12/1','1000000010');

IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;

INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)

VALUES(20100, 1, 'BR01', 100, 5.49);

IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;

INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)

VALUES(20100, 2, 'BR03', 100, 10.99);

IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;

COMMIT TRANSACTION

该事务处理块中包含了4条INSERT语句。在第一条INSERT语句之后定义了一个保留点,只要后面的任何一个INSERT操作失败,事务处理就能回退到这里。

在SQL Server中,检查一个名为@@ERROR的变量,看操作是否成功。若@@ERROR返回一个非0值,表示有错误发生,事务处理返回到保留点。若整个事务处理成功,发布COMMIT以保留数据。

posted @ 2016-12-04 19:43  Sumomo  阅读(263)  评论(0编辑  收藏  举报