Handwritten Text Recognition for manuscripts and early printed texts
Vda305 concurrency guerrero
1. Session
VDA305
Concurrency problems and
locking techniques in SQL
Server 2000 and VB.NET
Fernando G. Guerrero
SQL Server MVP
.NET Technical Lead
QA plc
October 2002
2. Quick info about Fernando
(2 milliseconds)
• MCSD, MCSE+Internet (W2K), MCDBA, MCT,
QA
SQL Server MVP
• This is where I work: QA, The best learning
environment in Europe
• Writing for SQL Sever Magazine and SQL
Server Professional
• This is my main web site: www.callsql.com
• This is my book (so far):
– Microsoft SQL Server 2000 Programming by
Example (ISBN : 0789724499, co-authored with Carlos
Eduardo Rojas)
• Currently writing on ADO.NET and SQL Server
2000
VS .NET Connections
4. Concurrency problems
• Lost Updates
• Uncommitted Dependency
• Inconsistent Analysis
• Phantom Reads
VS .NET Connections 4
5. Lost Updates (1)
Peter Paul
Peter UnitPric UnitPric
Paul
e e
10.0 10.0
VS .NET Connections
Mary
5
(SQL Server)
6. Lost Updates (2)
Peter Paul
Peter UnitPric @UP * UnitPric
Paul
e 1.2 e
10.0 12.0 10.0
DECLARE @UP money
SELECT @UP = UnitPrice
FROM Products
WHERE ProductID = 25
VS .NET Connections
Mary
6
(SQL Server)
7. Lost Updates (3)
Peter Paul
Peter UnitPric @UP * UnitPric @UP *
Paul
e 1.2 e 1.1
10.0 12.0 10.0 11.0
DECLARE @UP money
DECLARE @UP money
SELECT @UP = UnitPrice
FROM Products
WHERE ProductID = 25
SELECT @UP = UnitPrice
FROM Products
WHERE ProductID = 25
VS .NET Connections
Mary
7
(SQL Server)
8. Lost Updates (4)
Peter Paul
Peter UnitPric @UP * UnitPric @UP *
Paul
e 1.2 e 1.1
DECLARE @UP money 12.0 12.0 12.0 11.0 DECLARE @UP money
SELECT @UP = UnitPrice SELECT @UP = UnitPrice
FROM Products FROM Products
WHERE ProductID = 25 WHERE ProductID = 25
UPDATE Products
SET UnitPrice =
@UP * 1.2
WHERE ProductID = 25
VS .NET Connections
Mary
8
(SQL Server)
9. Lost Updates (5)
Peter Paul
Peter UnitPric @UP * UnitPric @UP *
Paul
e 1.2 e 1.1
DECLARE @UP money 11.0 12.0 11.0 11.0 DECLARE @UP money
SELECT @UP = UnitPrice SELECT @UP = UnitPrice
FROM Products FROM Products
WHERE ProductID = 25 WHERE ProductID = 25
UPDATE Products
SET UnitPrice = @UP * 1.2
WHERE ProductID = 25 UPDATE Products
SET UnitPrice =
@UP * 1.1
WHERE ProductID = 25
VS .NET Connections
Mary
9
(SQL Server)
10. Uncommitted Dependency (1)
Peter Paul
Peter UnitPric UnitPric
Paul
e e
10.0 10.0
VS .NET Connections
Mary
10
(SQL Server)
11. Uncommitted Dependency (2)
Peter Paul
Peter UnitPric UnitPric
Paul
e e
12.0 12.0
BEGIN TRANSACTION
UPDATE PRODUCTS
SET UnitPrice =
UnitPrice * 1.2
WHERE ProductID = 25
VS .NET Connections
Mary
11
(SQL Server)
12. Uncommitted Dependency (3)
Peter Paul
Peter UnitPric UnitPric @UP
Paul
e e
12.0 12.0 12.0
BEGIN TRANSACTION
DECLARE @UP money
UPDATE PRODUCTS
SET UnitPrice = UnitPrice * 1.2
WHERE ProductID = 25
SELECT @UP = UnitPrice
FROM Products (NOLOCK)
WHERE ProductID = 25
VS .NET Connections
Mary
12
(SQL Server)
13. Uncommitted Dependency (4)
Peter Paul
Peter UnitPric UnitPric @UP
Paul
e e
BEGIN TRANSACTION 12.0
10.0 12.0
10.0 12.0 DECLARE @UP money
UPDATE PRODUCTS SELECT @UP = UnitPrice
SET UnitPrice = UnitPrice * 1.2 FROM Products
WHERE ProductID = 25 WHERE ProductID = 25
ROLLBACK TRANSACTION
VS .NET Connections
Mary
13
(SQL Server)
14. Uncommitted Dependency (5)
Peter Paul
Peter UnitPric UnitPric @UP
Paul
e e
BEGIN TRANSACTION 10.0 10.0 12.0 DECLARE @UP money
UPDATE PRODUCTS SELECT @UP = UnitPrice
SET UnitPrice = UnitPrice * 1.2 FROM Products
WHERE ProductID = 25 WHERE ProductID = 25
ROLLBACK TRANSACTION
INSERT [Order details]
(
OrderID,
ProductID,
UnitPrice,
Quantity,
Discount)
VALUES (25365, 25,
VS .NET Connections
Mary @UP, 10, 0.1)
14
(SQL Server)
16. Inconsistent Analysis (2)
Peter
Peter @Count 830 Paul
@Total
@Average
@Total /
DECLARE @Count int,
@Count
@Total money,
@Average money
SELECT @Count =
COUNT(DISTINCT
OrderID)
FROM .NET Connections
VS
[Order Details] Mary 16
(SQL Server)
17. Inconsistent Analysis (3)
Peter
Peter @Count 830 Paul
@Total
DECLARE @Count int,
@Total money, @Average
@Average money
SELECT @Count = @Total /
COUNT(DISTINCT OrderID) @Count
FROM [Order Details]
UPDATE [Order details
SET Quantity = 600
WHERE OrderID = 10272
AND ProductID = 20
VS .NET Connections
Mary
17
(SQL Server)
18. Inconsistent Analysis (4)
Peter
Peter @Count 830 Paul
@Total 1304284.2
DECLARE @Count int, 4 UPDATE [Order details]
@Total money, SET Quantity = 600
@Average money @Average WHERE OrderID = 10272
SELECT @Count = AND ProductID = 20
COUNT(DISTINCT OrderID) @Total / 1571.43
FROM [Order Details]
@Count
SELECT @Total =
SUM(UnitPrice *
Quantity *
(1 – Discount))
FROM [Order Details]
VS .NET Connections
Mary
18
(SQL Server)
19. Inconsistent Analysis (5)
Peter
Peter @Count 830 Paul
@Total 1304284.2
DECLARE @Count int, 4 UPDATE [Order details]
@Total money, SET Quantity = 600
@Average money @Average WHERE OrderID = 10272
SELECT @Count = AND ProductID = 20
COUNT(DISTINCT OrderID) @Total / 1571.43
FROM [Order Details]
@Count
SELECT @Total =
SUM(UnitPrice *
Quantity *
(1 – Discount))
FROM [Order Details] UPDATE [Order
details]
SET Discount = 0.4
WHERE ProductID =
VS .NET Connections
Mary20
19
(SQL Server)
20. Inconsistent Analysis (6)
Peter
Peter @Count 830 Paul
@Total 1304284.2
DECLARE @Count int, 4 UPDATE [Order details]
@Total money, SET Quantity = 600
@Average money @Average 1542.78 WHERE OrderID = 10272
SELECT @Count = AND ProductID = 20
COUNT(DISTINCT OrderID) @Total / 1571.43
FROM [Order Details]
@Count UPDATE [Order details]
SET Discount = 0.4
SELECT @Total = WHERE ProductID = 20
SUM(UnitPrice *
Quantity *
(1 – Discount))
FROM [Order Details]
SELECT @Average =
AVG(TotalPrice)
FROM (…) AS TotOrders
VS .NET Connections
Mary
20
(SQL Server)
21. Phantom Reads (1)
OrderID ProductI UnitPrice
Peter D Paul
10259 37 20.8
10337 37 20.8
10408 37 20.8
10523 37 26.0
10847 37 26.0
10966 37 26.0
SELECT OrderID,
ProductID,
UnitPrice
FROM [Order Details]
WHERE ProductID = 37
VS .NET Connections
Mary
21
(SQL Server)
22. Phantom Reads (2)
OrderID ProductI UnitPrice
Peter D Paul
10259 37 20.80
10337 37 20.80
SELECT OrderID,
ProductID, 10408 37 20.80
UnitPrice
FROM [Order Details] 10523 37 26.00
WHERE ProductID = 37
10847 37 26.00
10966 37 26.00
10615 37
INSERT [Order
31.54
details]
(OrderID,
ProductID,
UnitPrice,
MaryQuantity,
(SQL Server) Discount)
VS .NET Connections 22
23. Phantom Reads (3)
OrderID ProductI UnitPrice
Peter D Paul
10259 37 20.80
10337 37 20.80
SELECT OrderID, INSERT [Order details]
ProductID, 10408 37 20.80 (OrderID, ProductID,
UnitPrice UnitPrice, Quantity,
FROM [Order Details] 10523 37 26.00
Discount)
WHERE ProductID = 37
10847 37 26.00 VALUES (10615, 37,
31.54, 20, 0.1)
10966 37 26.00
10615 37 31.54
SELECT OrderID,
ProductID,
UnitPrice
FROM [Order Details]
WHERE ProductID = 37
VS .NET Connections
Mary
23
(SQL Server)
24. Isolation levels
• Transact-SQL:
– READ COMMITTED
– READ UNCOMMITTED
– REPEATABLE READ
– SERIALIZABLE
• Extra .NET Isolation Levels:
– Chaos (not valid for SQLClient)
– Unspecified (not settable for SQLClient)
VS .NET Connections 24
25. Isolation levels vs. Concurrency
problems
P Problem
Isolation
S Solution
Level
X
SERIALIZABLE
solved by standard
UNCOMMITTED
REPEATABLE
COMMITTED
exclusive locks
READ
READ
READ
inside
transactions
Concurrency
Problem
Lost
Update
X X X X
Dirty Read P S S S
Inconsiste
VS .NET Connections nt P P S S 25
Analysis
26. READ COMMITTED
• Default isolation level
• Avoids Dirty Reads
– m yTr =
an
m yconn.Begi ans i Iol i
nTr acton( s atonLevelReadCom m it
. t
ed)
–S ELECT … FRO M … W I (
TH READCO M M I
TTED)
–S ELECT … FRO M … W I (
TH READPAS T)
– S TRANS
ET ACTI N IO LATI N LEVEL READ CO M M I
O S O TTED
• Requests Shared locks for the duration of the
reading operation
• Requests Exclusive locks for each modification 26
VS .NET Connections
27. READ UNCOMMITTED
• Isolation level only suitable for “sneaking
around”
– m yTr =
an
m yconn.Begi ans i Iol i
nTr acton( s atonLevelReadUnCom m
.
it
ted)
–S ELECT … FRO M … W I (
TH READUNCO M M ITTED)
–S ELECT … FRO M … W I ( LO CK)
TH NO
– S TRANS
ET ACTI N IO LATI N LEVEL READ UNCO M M I
O S O TTED
• Doesn’t request Shared locks at all
• Requests Exclusive locks for each modification
VS .NET Connections 27
28. REPEATABLE READ
• Quite a restrictive isolation level
• Avoids all concurrency problems, except
Phantom Reads
– m yTr =
an
m yconn.Begi ans i Iol i
nTr acton( s atonLevelRepeat eRe
. abl
ad)
–S ELECT … FRO M … W I (
TH REPEATABLEREAD)
– S TRANS
ET ACTI N IO LATI N LEVEL REPEATABLE READ
O S O
• Requests Shared locks for the duration of the
transaction
• Requests Exclusive locks for each modification 28
VS .NET Connections
29. SERIALIZABLE
• The most restrictive isolation level
• Avoids all concurrency problems
– m yTr =
an
m yconn.Begi ans i Iol i
nTr acton( s atonLevelS i i e)
. eralzabl
–S ELECT … FRO M … W I ( ERI ZABLE)
TH S ALI
–S ELECT … FRO M … W I ( LDLO CK)
TH HO
– S TRANS
ET ACTI N IO LATI N LEVEL S ALI
O S O ERI ZABLE
• Requests Shared locks for the duration of the
transaction
• Requests Exclusive locks for each modification
VS .NET Connections 29
34. Nested transactions
• @@TRANCOUNT tells you how many
transaction levels you are in
• For SQL Server there is only one actual
transaction
• Commit happens only when all nested
transactions are ended
• Rollback cancels all nested transactions at
once
VS .NET Connections 34
35. Transactions and Stored
Procedures
• After Rollback execution continues, but you are
outside transaction boundaries
• If Rollback happens inside a procedure, the
calling process receives error 266, Level 16:
– Transaction count after EXECUTE indicates that a
COMMIT or ROLLBACK TRANSACTION statement is
missing. Previous count = 1, current count = 0.
• Good idea to use save points and inform the
outer process using output parameters
VS .NET Connections 35
36. Transactions and Triggers
• After Rollback execution continues inside
the trigger, but you are outside transaction
boundaries and the process terminates
when the trigger does.
• Consider using INSTEAD OF triggers to
minimize rollbacks
• Consider using cancelling operations
instead of rollbacks
VS .NET Connections 36
39. .NET Automatic transactions
• Apply the TransactionAttribute to your class.
• Derive your class from the
ServicedComponent Class.
• Sign the assembly with a strong name.
– To sign the assembly using attributes create a
key pair using the Sn.exe utility.
– sn -k MCTCon.snk
VS .NET Connections 39
40. .NET Automatic transactions (2)
<Assembly: ApplicationName("MCTCON")>
<Assembly: AssemblyKeyFileAttribute("MCTCON.snk")>
<Transaction(TransactionOption.Required)> Public Class clsProduct
Inherits ServicedComponent
Dim myConnection As SqlConnection
<AutoComplete()> Public Sub RaisePrice(ByVal ProductID As Integer, ByVal
amount As Integer)
OpenConnection()
Updateproduct(ProductID, amount)
CloseConnection()
End Sub
VS .NET Connections 40
49. Hunting for locks
• Profiler can detect locks
• Performance Monitor counts locks
• Transaction Log registers transactions. It
doesn’t register locks
• Convert sp_lock into fn_lock
SELECT *
FROM ::fn_lock()
WHERE Status = 'WAIT'
VS .NET Connections 49
53. Locking techniques from ADO.NET
• Optimistic concurrency
• Pessimistic concurrency
• User-defined concurrency
VS .NET Connections 53
54. Optimistic concurrency
• Default behavior from DataAdapter
• Based on sp_executesql
• SET clause with all new values:
– Updated columns
– Unchanged columns
• WHERE clause with all old values:
– Updated columns
– Unchanged columns
VS .NET Connections 54
55. Pessimistic Concurrency
• Implemented through SqlCommand
objects and stored procedures
• Not scaleable:
– Requires maintaining connection open
– Open transaction
– Too much locking for too much time
• Necessary in some scenarios
VS .NET Connections 55
60. Do you want to know more?
• “Inside SQL Server 2000” (Kalen Delaney, MSPress)
• “Advanced Transact-SQL for SQL Server 2000” (Itzik
Ben-Gan & Tom Moreau, APress)
• “SQL Server 2000 Programming” (Robert Vieira, WROX)
• “Microsoft SQL Server 2000 Programming by Example”
(Fernando G. Guerrero & Carlos Eduardo Rojas, QUE)
• SQL Server 2000 Resource Kit (MSPress & TechNet)
• Visit the Microsoft public newsgroups:
– msnews.microsoft.com/microsoft.public.sqlserver.*
• Download the source code of this session from:
– http://www.callsql.com/en/articles
VS .NET Connections 60
61. Do you want to know even
more?
• Visit the Microsoft public newsgroups:
– msnews.microsoft.com/microsoft.public.sql
server.*
– msnews.microsoft.com/microsoft.public.dot
net.*
VS .NET Connections 61
62. Thank you!
Questions?
• Download the source code of this
session from:
– http://www.callsql.com/en/articles
• You can contact me at:
– fernan@guerrerog.org
VS .NET Connections
63. Thank you!
• Please drop off your
session evaluations in
the basket at the back
of the room!
• Your comments are
greatly appreciated!
VS .NET Connections