通过在会计读取相邻行的同时让销售经理插入行,创建幻像行。此操作会使新行以幻像行显示。
前提条件
本课假定您拥有在教程教程:了解幻像行开头的特权部分中列出的角色和特权。
在 [Sales Manager] 和 [Accountant] 窗口中分别执行以下语句,将隔离级别设置为 2:
SET TEMPORARY OPTION isolation_level = 2; |
会计执行以下语句,列出所有部门:
SELECT * FROM GROUPO.Departments ORDER BY DepartmentID; |
DepartmentID | DepartmentName | DepartmentHeadID |
---|---|---|
100 | R & D | 501 |
200 | Sales | 902 |
300 | Finance | 1293 |
400 | Marketing | 1576 |
500 | Shipping | 703 |
销售经理决定设立一个新部门,专门管理国外市场。Philip Chin(EmployeeID 为 129)将作为这个新部门的经理。销售经理执行以下语句为新部门创建一个新条目,该条目作为一个新行出现在销售经理窗口的表底部:
INSERT INTO GROUPO.Departments ( DepartmentID, DepartmentName, DepartmentHeadID ) VALUES( 600, 'Foreign Sales', 129 ); COMMIT; |
销售经理执行以下语句,列出所有部门:
SELECT * FROM GROUPO.Departments ORDER BY DepartmentID; |
DepartmentID | DepartmentName | DepartmentHeadID |
---|---|---|
100 | R & D | 501 |
200 | Sales | 902 |
300 | Finance | 1293 |
400 | Marketing | 1576 |
500 | Shipping | 703 |
600 | Foreign Sales | 129 |
但是,会计并不知道这个新部门。处于隔离级别 2 时,数据库服务器通过放置锁来确保所有行都不会发生更改,但却不会通过放置锁来防止其它事务插入新行。
会计只有再次执行 SELECT 语句才会发现这一新行。会计再次执行 SELECT 语句,查看附加到表的新行。
SELECT * FROM GROUPO.Departments ORDER BY DepartmentID; |
DepartmentID | DepartmentName | DepartmentHeadID |
---|---|---|
100 | R & D | 501 |
200 | Sales | 902 |
300 | Finance | 1293 |
400 | Marketing | 1576 |
500 | Shipping | 703 |
600 | Foreign Sales | 129 |
出现的新行被称作幻像行,这是因为,从会计的角度来看,该行就象幻影那样,不知从何而来。会计的连接处于隔离级别 2。在该级别上,数据库服务器只在会计使用的行上获取锁。而对其它行则不进行任何控制,因此没有任何限制阻止销售经理插入新行。
会计希望在将来避免这种奇异的事情发生,因此他将其当前事务的隔离级别提高到级别 3。会计执行以下语句:
SET TEMPORARY OPTION isolation_level = 3; SELECT * FROM GROUPO.Departments ORDER BY DepartmentID; |
而销售经理想要再增加一个部门来处理针对大型企业合作伙伴的销售业务。销售经理执行以下语句:
INSERT INTO GROUPO.Departments ( DepartmentID, DepartmentName, DepartmentHeadID ) VALUES( 700, 'Major Account Sales', 902 ); |
销售经理的窗口在执行该命令的过程中将会暂停,因为会计放置的锁阻止了该语句。在工具栏中,单击 [停止] 以中断这次输入。
在会计将他的隔离级别提高到级别 3 并再次选择了 Departments 表中的所有行之后,数据库服务器在该表中的每一行上都放置了防插入锁,并且添加了一个额外的幻像锁以防止在该表的末尾插入新行。当销售经理尝试在该表的末尾插入新行时,就是这最后一个锁阻塞了她的语句。
请注意,即使销售经理的连接仍处于隔离级别 2,她的语句也会被阻塞。数据库服务器按照每个事务的隔离级别和语句的要求放置防插入锁(与读锁定类似)。一旦放置这些锁定,所有其它并发事务必须都遵从。
为了避免更改 SQL Anywhere 示例数据,您应该回退未完成的插入 Major Account Sales 部门行的事务,并使用另一个事务删除 Foreign Sales 部门。
会计执行以下语句来降低隔离级别,从而使销售经理可以撤销对数据库的更改:
SET TEMPORARY OPTION isolation_level=3; |
销售经理执行以下语句来回退当前事务、删除之前插入的行并提交该操作:
ROLLBACK; DELETE FROM GROUPO.Departments WHERE DepartmentID = 600; COMMIT; |
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |