Professional Documents
Culture Documents
DBNote 07
DBNote 07
Chapter 7
Database Integrity and
Transactions
Jerry Post
Copyright © 2003
1
D Programming Environment
A Create code Tables DBMS
T (1) Within the query system
(2) In forms and reports
Queries
(1)
A (3) Hosted in external programs
If ( . . ) Then
Else . . .
SELECT . . .
B External
Program (3)
Forms &
Reports
End If
UPDATE . . .
A C++
if (. . .) {
S // embed SQL
SELECT …
(2)
If (Click) Then
} MsgBox . . .
E End If
2
D User-Defined Function
A CREATE FUNCTION EstimateCosts
(ListPrice Currency, ItemCategory VarChar)
T RETURNS Currency
BEGIN
IF (ItemCategory = ‘Clothing’) THEN
A ELSE
RETURN ListPrice * 0.5
B END IF
RETURN ListPrice * 0.75
A END
S
E
3
D Function to Perform Conditional Update
A CREATE FUNCTION IncreaseSalary
B END
UPDATE Employee SET Salary = Salary + Amt
WHERE EmployeeID = EmpID;
A END
RETURN Amt
S
E
4
D Looking Up Data
A CREATE FUNCTION IncreaseSalary
(EmpID INTEGER, Amt CURRENCY)
T RETURNS CURRENCY
DECLARE
CURRENCY MaxAmount;
A BEGIN
SELECT MaxRaise INTO MaxAmount
FROM CompanyLimits
B WHERE LimitName = ‘Raise’;
END
RETURN -1 -- error flag
5
D Data Trigger Events
A INSERT
T BEFORE DELETE AFTER
A UPDATE
B
Oracle additions:
A Tables ALTER, CREATE, DROP
User LOGOFF, LOGON
S Database SERVERERROR, SHUTDOWN, STARTUP
E
6
D Statement v. Row Triggers
A UPDATE Employee
T SQL SET Salary = Salary + 10000
WHERE EmployeeID=442
A OR EmployeeID=558
B Before Update
On table
Triggers for overall table After Update
On table
E
7
D Data Trigger Example
A CREATE TRIGGER LogSalaryChanges
T AFTER UPDATE OF Salary ON Employee
REFERENCING OLD ROW as oldrow
S
E
8
D Canceling Data Changes in Triggers
A CREATE TRIGGER TestDeletePresident
T BEFORE DELETE ON Employee
REFERENCING OLD ROW AS oldrow
A Inventory(ItemID, QOH, …)
SET QOH = QOH – newrow.Quantity
B AFTER UPDATE
WHEN newrow.QOH < newrow.Reorder
S Order(OrderID, OrderDate, …)
E
10
D Trigger Loop
A Employee(EID, Salary) AFTER UPDATE
IF newrow.Salary > 100000 THEN
T END
Add Bonus
11
D Transactions
Some transactions result in multiple
A changes.
These changes must all be Savings Accounts
S
machine crashes.
1. Subtract $1000 from savings.
Possibly: give users a chance to
(machine crashes)
reverse/undo a transaction. 2. Add $1000 to Checking.
E Performance gain by executing
transactions as a block.
(money disappears)
12
D Defining Transactions
A The computer needs to be told which
changes must be grouped into a
T transaction.
Turn on transaction processing.
A Signify a transaction start.
Signify the end.
B Success: save all changes
Failure: cancel all changes
E
13
D SQL Transaction Code
A
CREATE FUNCTION TransferMoney(Amount Currency, AccountFrom Number,
AccountTo Number) RETURNS NUMBER
curBalance Currency;
T
BEGIN
DECLARE HANDLER FOR SQLEXCEPTION
BEGIN
A
ROLLBACK;
Return -2; -- flag for completion error
END;
B
START TRANSACTION; -- optional
SELECT CurrentBalance INTO curBalance
FROM Accounts WHERE (AccountID = AccountFrom);
A
IF (curBalance < Amount) THEN
RETURN -1; -- flag for insufficient funds
END IF
S
UPDATE Accounts
SET CurrentBalance = CurrentBalance – Amount
WHERE AccountID = AccountFrom;
E
UPDATE Accounts
SET CurrentBalance = CurrentBalance + Amount
WHERE AccountID = AccountTo;
COMMIT;
RETURN 0; -- flag for success 14
END;
D SAVEPOINT
A start
SAVEPOINT
StartOptional commit
B
START TRANSACTION;
SELECT …
UPDATE …
A SAVEPOINT StartOptional;
UPDATE …
UPDATE …
S If error THEN
ROLLBACK TO SAVEPOINT StartOptional;
E
END IF
COMMIT;
15
D Concurrent Access
Concurrent Access Two processes
A Multiple users or Receive payment ($200)
processes changing the
T same data at the same
time.
Place new order ($150)
Initial balance $800
A Final data will be wrong! Result should be $800
-200 + 150 = $750
Force sequential
B Locking
Interference result is
either $600 or $950
Delayed, batch updates
A Receive Payment
Customers
Place New Order
ID Balance
S 1) Read balance
2) Subtract pmt
800
-200
Jones $800
$600
3) Read balance
5) Add order
800
150
16
D Pessimistic Locks: Serialization
A One answer to concurrent access is to prevent it.
T When a transaction needs to alter data, it places a
SERIALIZABLE lock on the data used, so no other transactions
A can even read the data until the first transaction is completed.
E
message that it is
4) Save new bal. 600
locked.
17
D SQL Pessimistic Lock
BEGIN
AccountID NUMBER, Amount Currency) RETURNS NUMBER
E
18
D Deadlock
A 1) Lock Data A
Deadlock
T Two (or more) processes have
placed locks on data and are
3) Wait for Data B
S 2) Lock Data B
4) Wait for Data A
E
19
D Lock Manager
A Resource Resource Resource Resource Resource
T Process1
A B
Lock
C D
Wait
E
B
Process3 Lock
A Process5 Wait
S
E
21
D Optimistic Locks for Simple Update
A
(1) Read the balance
T (2) Add the new order value
A (3) Write the new balance
A BEGIN
SELECT Amount INTO oldAmount
WHERE AccountNumber = AccountID;
B …
UPDATE Accounts
SET AccountBalance = AccountBalance - Amount
E
END IF
-- keep a counter to avoid infinite loops
END
END
23
D ACID Transactions
A
Atomicity: all changes succeed or fail together.
T Consistency: all data remain internally consistent
(when committed) and can be validated by
A application checks.
T
Restriction: not allowed to save any data
READ COMMITTED
Problem: Second transaction might change or delete data
A
sequentially.
But, still might encounter locks and deadlocks
S
E
25
D Phantom Rows
A SELECT SUM(QOH)
FROM Inventory
WHERE Price BETWEEN 10 and 20
T Included ItemID QOH Price
UPDATE Inventory
A in first
query
111
113
5
6
15
7
SET Price = Price/2
WHERE …
B 117
118
12
4
30
12
A 119 7 22 Additional rows
will be included in
120 8 17
S
the second query
SELECT SUM(QOH)
E FROM Inventory
WHERE Price BETWEEN 10 and 20
26
D Generated Keys
A Customer Table
A
a second table.
S
Overall drawbacks: neither method is likely to be
transportable. If you change the DBMS, you will have to
rewrite the procedures to generate keys.
E
28
D Auto-Generated Keys
A
T Create an order for a new customer:
A 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
S value? What happens if two transactions generate keys at
almost the same time on the same table?
E
29
D Key-Generation Routine
A
T Create an order for a new customer:
A This method ensures that unique keys are generated, and that
you can use the keys in multiple tables because you know the
value. But, none of it is automatic. It always requires
S procedures and sometimes data triggers.
E
30
D Database Cursors
A
Purpose Year Sales
B Why?
Performance.
A SQL cannot do everything.
Complex calculations.
E
31
D Database Cursor Program Structure
A DECLARE cursor1 CURSOR FOR
SELECT AccountBalance
T FROM Customer;
sumAccount, balance Currency;
SQLSTATE Char(5);
A BEGIN
sumAccount = 0;
OPEN cursor1;
B WHILE (SQLSTATE = ‘00000’)
BEGIN
S END
END IF
CLOSE cursor1;
E END
-- display the sumAccount or do a calculation
32
D Cursor Positioning with FETCH
A DECLARE cursor2 SCROLL CURSOR FOR
SELECT …
T OPEN cursor2;
FETCH LAST FROM cursor2 INTO …
Loop…
A FETCH PRIOR FROM cursor2 INTO …
End loop
B
CLOSE cursor2;
33
D Problems with Multiple Users
T
Name Sales Name Sales
Alice 444,321 Alice 444,321
Carl 254,998 Bob 333,229
New row is
A Donna
Ed
652,004
411,736
added--while
code is running.
Carl
Donna
Ed
254,998
652,004
411,736
B The SQL standard can prevent this problem with the
A INSENSITIVE option:
DECLARE cursor3 INSENSITIVE CURSOR FOR …
S But, this is an expensive approach, because
E the DBMS usually makes a copy of the data.
Instead, avoid moving backwards.
34
D Changing Data with Cursors
A DECLARE cursor1 CURSOR FOR
SELECT Year, Sales, Gain
FROM SalesTotal
Year
2000
Sales
151,039
Gain
T ORDER BY Year
FOR UPDATE OF Gain;
2001
2002
179,332
195,453
priorSales, curYear, curSales, curGain
A BEGIN
priorSales = 0;
2003
2004
221,883
223,748
B OPEN cursor1;
Loop:
FETCH cursor1 INTO curYear, curSales, curGain
A UPDATE SalesTotal
SET Gain = Sales – priorSales
WHERE CURRENT OF cursor1;
S priorSales = curSales;
Until end of rows
E END
CLOSE cursor1;
COMMIT;
35
D Dynamic Parameterized Cursor Queries
A DECLARE cursor2 CURSOR FOR
SELECT ItemID, Description, Price
T FROM Inventory
WHERE Price < :maxPrice;
A
maxPrice Currency;
BEGIN
maxPrice = … -- from user or other query
B OPEN cursor2;
Loop:
-- runs query with current value
S
END
E from within the procedure code. The value is applied when the
cursor is opened.
36
D Sally’s Pet Store Inventory
A
Inventory method 1: calculate the current quantity on
T hand by totaling all purchases and sales every time
the total is needed.
A Drawback: performance
Inventory method 2: keep a running balance in the
B inventory table and update it when an item is
purchased or sold.
A Drawback: tricky code
T
ItemID
Description Add items purchased
QuantityOnHand Subtract items sold
A ListPrice
Category Adjust for shrink
B SaleItem
A SaleID
ItemID
S
Quantity
SalePrice
E
38
D Inventory Events
A SaleItem For a new sale, a row is added to
the SaleItem table.
SaleID
T ItemID
Quantity
A sale or an item could be
removed because of a clerical
39
D New Sale: Insert SaleItem Row
A CREATE TRIGGER NewSaleItem
AFTER INSERT ON SaleItem
T REFERENCING NEW ROW AS newrow
FOR EACH ROW
A
UPDATE Merchandise
SET QuantityOnHand = QuantityOnHand – newrow.Quantity
WHERE ItemID = newrow.ItemID;
B
A
S
E
40
D Delete SaleItem Row
A CREATE TRIGGER DeleteSaleItem
AFTER DELETE ON SaleItem
T REFERENCING OLD ROW AS oldrow
FOR EACH ROW
A
UPDATE Merchandise
SET QuantityOnHand = QuantityOnHand + oldrow.Quantity
WHERE ItemID = oldrow.ItemID;
B
A
S
E
41
D Quantity Changed Event
A CREATE TRIGGER UpdateSaleItem
AFTER UPDATE ON SaleItem
T REFERENCING OLD ROW AS oldrow
NEW ROW AS newrow
A
FOR EACH ROW
UPDATE Merchandise
SET QuantityOnHand = QuantityOnHand
B + oldrow.Quantity – newrow.Quantity
WHERE ItemID = oldrow.ItemID;
A
S
E
42
D ItemID or Quantity Changed Event
A CREATE TRIGGER UpdateSaleItem
AFTER UPDATE ON SaleItem
T REFERENCING OLD ROW AS oldrow
NEW ROW AS newrow
A
FOR EACH ROW
BEGIN
UPDATE Merchandise
A UPDATE Merchandise
SET QuantityOnHand = QuantityOnHand – newRow.Quantity
S
WHERE ItemID = newrow.ItemID;
COMMIT;
END
E
43