Presentation is loading. Please wait.

Presentation is loading. Please wait.

DB Integrity & Transactions Part 2

Similar presentations


Presentation on theme: "DB Integrity & Transactions Part 2"— Presentation transcript:

1 DB Integrity & Transactions Part 2
IS240 – DBMS Lecture #12 – M. E. Kabay, PhD, CISSP-ISSMP Assoc. Prof. Information Assurance School of Business & Cyber Studies, Norwich University V: Class Notes Copyright © 2004 M. E. Kabay. All rights reserved Page 1

2 Objectives Define elements of ACID transactions Atomicity Consistency
Isolation Durability Define SQL Isolation Levels What are phantom rows and how do we avoid them? How are internal key values generated and used in updates in the face of concurrency? What is the purpose of database cursors? Copyright © 2004 M. E. Kabay. All rights reserved Page 2

3 Topics ACID Transactions SQL 99/2003 Isolation Levels Phantom Rows
Generated Keys Database Cursors Sally’s Pet Store Inventory Copyright © 2004 M. E. Kabay. All rights reserved Page 3

4 ACID Transactions Atomicity: all changes succeed or fail together.
Consistency: all data remain internally consistent (when committed) and can be validated by application checks. Isolation: The system gives each transaction the perception that it is running in isolation. There are no concurrent access issues. Durability: When a transaction is committed, all changes are permanently saved even if there is a hardware or system failure. ACID transactions. The acronym highlights four of the main integrity features required of transactions. Copyright © 2004 M. E. Kabay. All rights reserved Page 4

5 SQL 99/2003 Isolation Levels READ UNCOMMITTED
Problem: might read dirty data that is rolled back Restriction: not allowed to save any data READ COMMITTED Problem: Second transaction might change or delete data Restriction: Need optimistic concurrency handling REPEATABLE READ Problem: Phantom rows caused by concurrent access SERIALIZABLE Provides same level of control as if all transactions were run sequentially. But, still might encounter locks and deadlocks Remember to LOCK in SAME ORDER and UNLOCK in REVERSE ORDER! Copyright © 2004 M. E. Kabay. All rights reserved Page 5

6 Phantom Rows ALICE BOB ALICE SELECT SUM(QOH) FROM Inventory
WHERE Price BETWEEN 10 and 20 Result: = 17 BOB INSERT INTO Inventory VALUES (121, 7, 16) VALUES (122, 3, 14) 17 8 120 16 7 121 14 3 122 22 119 12 4 118 30 117 6 113 15 5 111 Price QOH ItemID Included in first query Additional or changed rows will be included in the second query, which may cause contradictions in results Phantom rows. The first SELECT statement will select only three rows of data. When the second transaction runs, additional rows will match the criteria, so that the second time the query runs, it will return a different result, because it includes the phantom rows. ALICE SELECT SUM(QOH) FROM Inventory WHERE Price BETWEEN 10 and 20 Result: = 27 Copyright © 2004 M. E. Kabay. All rights reserved Page 6

7 Generated Keys Create an order for a new customer:
Customer Table CustomerID, Name, … Create an order for a new customer: (1) Create new key for CustomerID (2) INSERT row into Customer (3) Create key for new OrderID (4) INSERT row into Order Order Table OrderID, CustomerID, … Generated keys. Creating an order for a new customer requires generating a CustomerID key that is used in the Customer table and must be stored so it can be used in the Order table. Problem: What if someone concurrently generates another autokey just as you are trying to use the one you created? Generally the DBMS remembers only the latest autokey! Copyright © 2004 M. E. Kabay. All rights reserved Page 7

8 Methods to Generate Keys
The DBMS generates key values automatically whenever a row is inserted into a table. Drawback: it is tricky to get the generated value to use it in a second table. A separate key generator is called by a programmer to create a new key for a specified table. Drawback: programmers have to write code to generate a key for every table and each row insertion. Overall drawbacks: neither method is likely to be transportable. If you change the DBMS, you will have to rewrite the procedures to generate keys. Copyright © 2004 M. E. Kabay. All rights reserved Page 8

9 Auto-Generated Keys Create an order for a new customer:
INSERT row into Customer Get the key value that was generated Verify the key value is correct. How? INSERT row into Order Major problem: Step 2 requires that the DBMS return the key value that was most recently generated. How do you know it is the right value? What happens if two transactions generate keys at almost the same time on the same table? Auto-generated keys. The process seems relatively easy when the DBMS automatically generates keys. However, what happens at step 2 if two transactions generate a new key value on the same table at almost the same time? Copyright © 2004 M. E. Kabay. All rights reserved Page 9

10 Key-Generation Routine
Create an order for a new customer: Generate a key for CustomerID INSERT row into Customer Generate a key for OrderID INSERT row into Order This method ensures that unique keys are generated You can use the keys in multiple tables because you know the value But none of it is automatic Always requires procedures and sometimes data triggers Key-generation routine. The steps are not difficult, but programmers must add them for every table and every routine that inserts data. Copyright © 2004 M. E. Kabay. All rights reserved Page 10

11 Topics ACID Transactions SQL 99/2003 Isolation Levels Phantom Rows
Generated Keys Database Cursors Sally’s Pet Store Inventory Copyright © 2004 M. E. Kabay. All rights reserved Page 11

12 Database Cursors Purpose
Year Sales ,321 ,998 ,004 ,736 Purpose Track through table or query one row at a time. Data cursor is a pointer to active row. Why? Performance. SQL cannot do everything. Complex calculations. Compare multiple rows. Copyright © 2004 M. E. Kabay. All rights reserved Page 12

13 Database Cursor Program Structure
DECLARE cursor1 CURSOR FOR SELECT AccountBalance FROM Customer; sumAccount, balance Currency; SQLSTATE Char(5); BEGIN sumAccount = 0; OPEN cursor1; WHILE (SQLSTATE = ‘00000’) FETCH cursor1 INTO balance; IF (SQLSTATE = ‘00000’) THEN sumAccount = sumAccount + balance; END IF END CLOSE cursor1; -- display the sumAccount or do a calculation SQL cursor structure. DECLARE, OPEN, FETCH, and CLOSE are the main statements in the SQL standard. Copyright © 2004 M. E. Kabay. All rights reserved Page 13

14 Cursor Positioning with FETCH
DECLARE cursor2 SCROLL CURSOR FOR SELECT … OPEN cursor2; FETCH LAST FROM cursor2 INTO … Loop… FETCH PRIOR FROM cursor2 INTO … End loop CLOSE cursor2; FETCH positioning options: FETCH NEXT next row FETCH PRIOR prior row FETCH FIRST first row FETCH LAST last row FETCH ABSOLUTE 5 fifth row FETCH RELATIVE -3 back 3 rows FETCH options. A scrollable cursor can move in either direction. This code moves to the last row and then moves backward through the table. Other FETCH options include FIRST, ABSOLUTE, and RELATIVE. Copyright © 2004 M. E. Kabay. All rights reserved Page 14

15 Problems with Multiple Users
Original Data Modified Data Name Sales Alice 444,321 Carl 254,998 Donna 652,004 Ed 411,736 Name Sales Alice 444,321 Bob 333,229 Carl 254,998 Donna 652,004 Ed 411,736 New row is added--while code is running. The SQL standard can prevent this problem with the INSENSITIVE option: DECLARE cursor3 INSENSITIVE CURSOR FOR … Transaction concurrency in cursor code. Your cursor code has tracked down through the data to Carl. It then tries to go back to the prior row with FETCH PRIOR. But, if another transaction has inserted a new row (Bob) in the meantime, your code will pick up that one instead of the original (Alice). But this is an expensive approach because the DBMS usually makes a copy of the data. Instead, avoid moving backwards. Copyright © 2004 M. E. Kabay. All rights reserved Page 15

16 Changing Data with Cursors
DECLARE cursor1 CURSOR FOR SELECT Year, Sales, Gain FROM SalesTotal ORDER BY Year FOR UPDATE OF Gain; priorSales, curYear, curSales, curGain BEGIN priorSales = 0; OPEN cursor1; Loop: FETCH cursor1 INTO curYear, curSales, curGain UPDATE SalesTotal SET Gain = Sales – priorSales WHERE CURRENT OF cursor1; priorSales = curSales; Until end of rows CLOSE cursor1; COMMIT; END Year Sales Gain 2000 151,039 2001 179,332 2002 195,453 2003 221,883 2004 223,748 Sales analysis table. A standard SELECT query can compute and save the sales total by year. You now need to write a cursor-based procedure to compute the sales gain from the prior year. Copyright © 2004 M. E. Kabay. All rights reserved Page 16

17 Sally’s Pet Store Inventory
Inventory method 1: calculate the current quantity on hand by totaling all purchases and sales every time the total is needed. Drawback: performance Inventory method 2: keep a running balance in the inventory table and update it when an item is purchased or sold. Drawback: tricky code Also, you need an adjustment process for “inventory shrink” Corrections of mistakes Copyright © 2004 M. E. Kabay. All rights reserved Page 17

18 Inventory QuantityOnHand
Merchandise ItemID Description QuantityOnHand ListPrice Category Add items purchased Subtract items sold Adjust for shrink SaleItem SaleID ItemID Quantity SalePrice Processing inventory changes. When an item is sold, the quantity sold is entered into the SaleItem table. This value has to be subtracted from the QuantityOnHand in the Merchandise table. Copyright © 2004 M. E. Kabay. All rights reserved Page 18

19 Inventory Events A USER MAY Add a row. Delete a row. Update Quantity.
SaleItem For a new sale, a row is added to the SaleItem table. A sale or an item could be removed because of a clerical error or the customer changes his or her mind. A SaleItem row will be deleted. An item could be returned, or the quantity could be adjusted because of a counting error. The Quantity is updated in the SaleItem table. An item is entered incorrectly. ItemID is updated in the SaleItem table. SaleID ItemID Quantity SalePrice A USER MAY Add a row. Delete a row. Update Quantity. Update ItemID. SaleItem events. Driven by business operations, four major events can arise in the SaleItem table. The QuantityOnHand must be altered in the Merchandise table for each of these events. Copyright © 2004 M. E. Kabay. All rights reserved Page 19

20 New Sale: Insert SaleItem Row
CREATE TRIGGER NewSaleItem AFTER INSERT ON SaleItem REFERENCING NEW ROW AS newrow FOR EACH ROW UPDATE Merchandise SET QuantityOnHand = QuantityOnHand – newrow.Quantity WHERE ItemID = newrow.ItemID; New Sale trigger. Inserting a new row triggers the event to subtract the newly entered quantity sold from the quantity on hand. Copyright © 2004 M. E. Kabay. All rights reserved Page 20

21 Delete SaleItem Row CREATE TRIGGER DeleteSaleItem
AFTER DELETE ON SaleItem REFERENCING OLD ROW AS oldrow FOR EACH ROW UPDATE Merchandise SET QuantityOnHand = QuantityOnHand + oldrow.Quantity WHERE ItemID = oldrow.ItemID; Delete Row trigger. This trigger reverses the original subtraction by adding the Quantity back in. Copyright © 2004 M. E. Kabay. All rights reserved Page 21

22 Inventory Update Sequence
SaleItem Clerk Event Code Merchandise SaleID 101 ItemID 15 Quantity 10 Quantity 8 Enter new sale item, enter Quantity of 10. 3. Change Quantity to 8. 2. Subtract Quantity 10 from QOH. 4. Subtract Quantity 8 from QOH. QOH 50 QOH 40 QOH 32 Solution that corrects for change 4. Add original Quantity 10 back and subtract Quantity 8 from QOH. QOH 42 OOPS Errors arise if you do not handle changes in quantity. If Quantity is changed, you must add back the old value and then subtract the new value. The top steps show the error in QOH if you do not handle changes. Copyright © 2004 M. E. Kabay. All rights reserved Page 22

23 Quantity Changed Event
CREATE TRIGGER UpdateSaleItem AFTER UPDATE ON SaleItem REFERENCING OLD ROW AS oldrow NEW ROW AS newrow FOR EACH ROW UPDATE Merchandise SET QuantityOnHand = QuantityOnHand + oldrow.Quantity – newrow.Quantity WHERE ItemID = oldrow.ItemID; Update Quantity trigger. If Quantity is changed, you must add back the old value and then subtract the new value. Copyright © 2004 M. E. Kabay. All rights reserved Page 23

24 ItemID or Quantity Changed Event
CREATE TRIGGER UpdateSaleItem AFTER UPDATE ON SaleItem REFERENCING OLD ROW AS oldrow NEW ROW AS newrow FOR EACH ROW BEGIN UPDATE Merchandise SET QuantityOnHand = QuantityOnHand + oldRow.Quantity WHERE ItemID = oldrow.ItemID; SET QuantityOnHand = QuantityOnHand – newRow.Quantity WHERE ItemID = newrow.ItemID; COMMIT; END Final update trigger. If the ItemID is changed, you must restore the total for the original item and subtract the new quantity from the new ItemID. Copyright © 2004 M. E. Kabay. All rights reserved Page 24

25 DISCUSSION Copyright © 2004 M. E. Kabay. All rights reserved Page 25


Download ppt "DB Integrity & Transactions Part 2"

Similar presentations


Ads by Google