This tutorial continues the same scenario. The Accountant and the Sales Manager both have tasks that involve the SalesOrder and SalesOrderItems tables. The Accountant needs to verify the amounts of the commission checks paid to the sales employees for the sales they made during the month of April 2001. The Sales Manager notices that a few orders have not been added to the database and wants to add them.
Their work demonstrates phantom locking. A phantom lock is a shared lock placed on an indexed scan position to prevent phantom rows. When a transaction at isolation level 3 selects rows which match a given criterion, the database server places anti-insert locks to stop other transactions from inserting rows which would also match. The number of locks placed on your behalf depends both on the search criterion and on the design of your database.
If you have not done so, follow steps 1 through 4 of the Tutorial: Phantom rows, which describe how to start two instances of Interactive SQL.
SET TEMPORARY OPTION isolation_level = 2; |
Enter the following command in the Accountant's window. Prices, sales order information, and employee data are stored in separate tables. Join these tables using the foreign key relationships to combine the necessary pieces of information.
SELECT EmployeeID, GivenName, Surname, SUM(SalesOrderItems.Quantity * UnitPrice) AS "April sales" FROM Employees KEY JOIN SalesOrders KEY JOIN SalesOrderItems KEY JOIN Products WHERE '2001-04-01' <= OrderDate AND OrderDate < '2001-05-01' GROUP BY EmployeeID, GivenName, Surname ORDER BY EmployeeID; |
EmployeeID | GivenName | Surname | April sales |
---|---|---|---|
129 | Philip | Chin | 2160.00 |
195 | Marc | Dill | 2568.00 |
299 | Rollin | Overbey | 5760.00 |
467 | James | Klobucher | 3228.00 |
... | ... | ... | ... |
In the Sales Manager's window, enter the following commands. The Sales order and the items are entered in separate tables because one order can contain many items. You should create the entry for the sales order before you add items to it. To maintain referential integrity, the database server allows a transaction to add items to an order only if that order already exists.
INSERT into SalesOrders VALUES ( 2653, 174, '2001-04-22', 'r1', 'Central', 129); INSERT into SalesOrderItems VALUES ( 2653, 1, 601, 100, '2001-04-25' ); COMMIT; |
In the Accountant's window, calculate the April sales totals again. Use the same command, and observe that Philip Chin's April sales changes to $4560.00.
EmployeeID | GivenName | Surname | April sales |
---|---|---|---|
129 | Philip | Chin | 4560.00 |
195 | Marc | Dill | 2568.00 |
299 | Rollin | Overbey | 5760.00 |
467 | James | Klobucher | 3228.00 |
... | ... | ... | ... |
Imagine that the Accountant now marks all orders placed in April to indicate that commission has been paid. The order that the Sales Manager just entered might be found in the second search and marked as paid, even though it was not included in Philip's total April sales!
In the Sales Manager's window, execute the following statements to remove the new order.
DELETE FROM SalesOrderItems WHERE ID = 2653; DELETE FROM SalesOrders WHERE ID = 2653; COMMIT; |
ROLLBACK; SET TEMPORARY OPTION isolation_level = 3; |
SELECT EmployeeID, GivenName, Surname, SUM(SalesOrderItems.Quantity * UnitPrice) AS "April sales" FROM Employees KEY JOIN SalesOrders KEY JOIN SalesOrderItems KEY JOIN Products WHERE '2001-04-01' <= OrderDate AND OrderDate < '2001-05-01' GROUP BY EmployeeID, GivenName, Surname; |
Because you set the isolation to level 3, the database server automatically places anti-insert locks to ensure that the Sales Manager cannot insert April order items until the Accountant finishes his transaction.
INSERT INTO SalesOrders VALUES ( 2653, 174, '2001-04-22', 'r1','Central', 129); |
The Sales Manager's window stops responding, and the operation does not complete. On the toolbar, click Interrupt The SQL Statement (or choose SQL » Stop) to interrupt this entry.
Change the date of the command to May 05 and try again.
INSERT INTO SalesOrders VALUES ( 2653, 174, '2001-05-05', 'r1', 'Central', 129); |
The Sales Manager's window stops responding again. On the toolbar, click Interrupt The SQL Statement (or choose SQL » Stop) to interrupt this entry. Although the database server places no more locks than necessary to prevent insertions, these locks have the potential to interfere with a large number of other transactions.
The database server places locks in table indexes. For example, it places a phantom lock in an index so a new row cannot be inserted immediately before it. However, when no suitable index is present, it must lock every row in the table.
In some situations, anti-insert locks may block some insertions into a table, yet allow others.
INSERT INTO SalesOrderItems VALUES ( 2651, 2, 302, 4, '2001-05-22' ); |
The Sales Manager's window stops responding. On the toolbar, click Interrupt The SQL Statement (or choose SQL » Stop) to interrupt this entry.
ROLLBACK; |
Enter the same command in the Accountant's window.
ROLLBACK; |
You may now close both windows.
Send feedback about this page via email or DocCommentXchange | Copyright © 2008, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.0 |