创建非可重复读取,即会计尝试读取一个正在由销售经理进行修改的行,因此在同一事务中得到了两个不同的结果。
前提条件
本课假定您拥有在教程教程:了解非可重复读取开头的特权部分中列出的角色和特权。
执行以下语句,将会计的连接隔离级别设置为 1:
SET TEMPORARY OPTION isolation_level = 1; |
在销售经理的窗口中执行以下语句,将隔离级别设置为 1:
SET TEMPORARY OPTION isolation_level = 1; |
会计执行以下语句,列出太阳帽的价格:
SELECT ID, Name, UnitPrice FROM GROUPO.Products; |
ID | Name | UnitPrice |
---|---|---|
300 | Tee Shirt | 9.00 |
301 | Tee Shirt | 14.00 |
302 | Tee Shirt | 14.00 |
400 | Baseball Cap | 9.00 |
401 | Baseball Cap | 10.00 |
500 | Visor | 7.00 |
501 | Visor | 7.00 |
... | ... | ... |
销售经理执行以下语句,为塑料太阳帽定一个新的销售价格:
SELECT ID, Name, UnitPrice FROM GROUPO.Products WHERE Name = 'Visor'; UPDATE GROUPO.Products SET UnitPrice = 5.95 WHERE ID = 501; COMMIT; SELECT ID, Name, UnitPrice FROM GROUPO.Products WHERE Name = 'Visor'; |
ID | Name | UnitPrice |
---|---|---|
500 | Visor | 7.00 |
501 | Visor | 5.95 |
比较 [Sales Manager] 窗口中太阳帽的价格和 [Accountant] 窗口中相同太阳帽的价格。会计再次执行 SELECT 语句,并查看销售经理的新销售价格:
SELECT ID, Name, UnitPrice FROM GROUPO.Products; |
ID | Name | UnitPrice |
---|---|---|
300 | Tee Shirt | 9.00 |
301 | Tee Shirt | 14.00 |
302 | Tee Shirt | 14.00 |
400 | Baseball Cap | 9.00 |
401 | Baseball Cap | 10.00 |
500 | Visor | 7.00 |
501 | Visor | 5.95 |
... | ... | ... |
这种不一致被称作非可重复读取,因为在同一事务 中再次执行相同的 SELECT 命令后,会计不会得到相同的结果。
当然,如果会计已经完成了该事务,例如,在再次使用 SELECT 之前发出了 COMMIT 或 ROLLBACK 语句,情况则有所不同。该数据库可供多个用户同时使用,而且完全允许某人在会计执行事务之前或之后更改值。结果中的变化仅仅因为发生在执行其事务的过程中才不一致。这种情况将导致调度不可序列化。
会计注意到了这种情况,并决定从现在开始不希望看到价格发生更改。隔离级别 2 消除了非可重复读取。作为会计,执行以下语句:
SET TEMPORARY OPTION isolation_level = 2; SELECT ID, Name, UnitPrice FROM GROUPO.Products; |
销售经理决定最好将塑料太阳帽的销售推迟到下个星期,这样,她就不必为预计明天会收到的一个大订单报那个较低的价格。销售经理尝试执行以下语句。该语句开始执行,然后窗口会呈现冻结状态。
UPDATE GROUPO.Products SET UnitPrice = 7.00 WHERE ID = 501; |
数据库服务器在隔离级别 2 上必须确保可重复读取。由于会计正在使用隔离级别 2,因此数据库服务器在会计读取的 Products 表的每一行上都放置一个读锁定。当销售经理尝试将价格更改回原来的值时,她的事务必须在 Products 表中包含塑料太阳帽的那一行上获取一个写锁定。由于写锁定是独占的,因此她的事务必须等到会计的事务释放其读锁定后才能继续执行。
会计查看完价格后,由于他不希望无意中更改了数据库,因此使用 ROLLBACK 语句完成他的事务。
ROLLBACK; |
数据库服务器执行该语句后,销售经理的事务完成。
ID | Name | UnitPrice |
---|---|---|
500 | Visor | 7.00 |
501 | Visor | 7.00 |
销售经理现在就可以完成事务了。她希望提交她所做的更改,恢复到原来的价格:
COMMIT; |
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |