I am trying to implement Optimistic Concurrency using EntitySpaces, SQL Server, and a RowVersion timestamp column, and am running into problems when attempting to delete a record that has been modified outside of the transaction.
1) I do a LoadAll on the collection
2) I pause Visual Studio debugger, and modify a record in the database in Microsoft SQL Server Management Studio, unpause the debugger...
3) I attempt to delete the record (same one that was modified) from within a transaction
4) I save the collection
5) I complete the transaction "successfully".
My problem is that if the record was modified outside of the transaction, the Delete should not have been successful, I believe this is supposed to throw a concurrency exception.
According to MSDN (http://msdn2.microsoft.com/en-us/library/ms713899.aspx):
"In optimistic concurrency, a row is left unlocked until the time comes to update or delete it. At that point, the row is reread and checked to see if it has been changed since it was last read. If the row has changed, the update or delete fails and must be tried again."
In this case, the row HAS changed, but the DELETE action does not fail.
Code:
1 Dim col As New TestBed.Library.DataAccess.LookupValueItemCollection
2 col.LoadAll()
3 Dim x As TestBed.Library.DataAccess.LookupValueItem
4 Using trans As EntitySpaces.Interfaces.esTransactionScope = New EntitySpaces.Interfaces.esTransactionScope()
5 For i As Integer = 0 To col.Count - 1
6 If i = col.Count - 1 Then
7 x = DirectCast(col.Item(i), TestBed.Library.DataAccess.LookupValueItem)
8 x.MarkAsDeleted()
9 End If
10 Next
11 col.Save()
12 trans.Complete()
13 End Using
14
In this snippet, I am deleting the last row in the collection. When debugging, I pause on Line 5, alter the last record in my table, then unpause. When the code is done executing, the row that was previously modified AFTER the collection was loaded is now deleted. If I alter line 8 to just alter a value in the row (x.Name = "new name"), I do get a concurrency exception.
The definition of my table is below:
Code:
CREATE TABLE [dbo].[LookupValueItem](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LookupValueId] [int] NOT NULL,
[Name] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Value] [int] NOT NULL,
[RowVersion] [timestamp] NOT NULL,
CONSTRAINT [PK_LookupValueItem] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
Eric