optimistic locking using timestamp
|
|
Thread rating:  |
endy_tj - 29 Dec 2005 12:30 GMT I am using SQL Server 2000, VB6, and ADO recordset. I have a table containing a column with datatype of timestamp. I open my ADO connection by specifying client cursor location. The recordset is opened with static cursor type and batch optimistic lock type.
As I understand, this setup will give me concurrency control by automatically performing optimistic locking, but that is not the case.
I tried opening two recordsets for that table, tried updating different columns of the same row, then updatebatch. Both succeed! Why? What did I miss?
In the above case I want the first updatebatch to succeed, and the second to fail, because of the conflict.
-- Endy
Paul Clement - 29 Dec 2005 15:47 GMT ¤ I am using SQL Server 2000, VB6, and ADO recordset. I have a table ¤ containing a column with datatype of timestamp. I open my ADO ¤ connection by specifying client cursor location. The recordset is ¤ opened with static cursor type and batch optimistic lock type. ¤ ¤ As I understand, this setup will give me concurrency control by ¤ automatically performing optimistic locking, but that is not the case. ¤ ¤ I tried opening two recordsets for that table, tried updating different ¤ columns of the same row, then updatebatch. Both succeed! Why? What did ¤ I miss? ¤ ¤ In the above case I want the first updatebatch to succeed, and the ¤ second to fail, because of the conflict.
What happens if you use a keyset cursor type?
You might want to post your test code so we can see exactly how you are attempting to trigger the concurrency problem.
Paul ~~~~ Microsoft MVP (Visual Basic)
endy_tj - 29 Dec 2005 20:04 GMT I have tried keyset, but the result is the same. Here is the sample source:
SQL part:
create table periods ( id bigint not null, ts timestamp, code varchar(50), name varchar(100) );
alter table periods add constraint PK_PERIOD primary key (id);
insert into periods(id, code, name) values(1, '111', '222');
VB part:
Dim conn As New ADODB.Connection conn.CursorLocation = adUseClient ' i have also tried server conn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ACC;Data Source=ENDY"
Dim rs1 As New ADODB.Recordset, rs2 As New ADODB.Recordset rs1.Open "select * from periods", conn, _ adOpenStatic, adLockBatchOptimistic ' i have also tried keyset rs2.Open "select * from periods", conn, adOpenStatic, adLockBatchOptimistic
rs1.Fields("code") = "abc" ' old: 111 new: abc rs2.Fields("name") = "def" ' old: 222 new: def
rs1.UpdateBatch ' code: abc name: 222 rs2.UpdateBatch ' this should fail, but it succeeded, code: abc name: def
If timestamp doesn't work, what do you suggest I do to provide optimistic locking?
endy_tj - 30 Dec 2005 23:29 GMT > ¤ I am using SQL Server 2000, VB6, and ADO recordset. I have a table > ¤ containing a column with datatype of timestamp. I open my ADO [quoted text clipped - 19 lines] > ~~~~ > Microsoft MVP (Visual Basic) I have tried keyset, but the result is the same. Here is the sample source:
SQL part:
create table periods ( id bigint not null, ts timestamp, code varchar(50), name varchar(100) );
alter table periods add constraint PK_PERIOD primary key (id);
insert into periods(id, code, name) values(1, '111', '222');
VB part:
Dim conn As New ADODB.Connection conn.CursorLocation = adUseClient ' i have also tried server conn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ACC;Data Source=ENDY"
Dim rs1 As New ADODB.Recordset, rs2 As New ADODB.Recordset rs1.Open "select * from periods", conn, _ adOpenStatic, adLockBatchOptimistic ' i have also tried keyset rs2.Open "select * from periods", conn, _ adOpenStatic, adLockBatchOptimistic
rs1.Fields("code") = "abc" ' old: 111 new: abc rs2.Fields("name") = "def" ' old: 222 new: def
rs1.UpdateBatch ' code: abc name: 222 rs2.UpdateBatch ' this should fail, but it succeeded ' code: abc name: def
If timestamp doesn't work, what do you suggest I do to provide optimistic locking?
Ralph - 31 Dec 2005 00:22 GMT Paul Clement wrote:
> ¤ I am using SQL Server 2000, VB6, and ADO recordset. I have a table > ¤ containing a column with datatype of timestamp. I open my ADO [quoted text clipped - 19 lines] > ~~~~ > Microsoft MVP (Visual Basic) I have tried keyset, but the result is the same. Here is the sample source:
SQL part:
create table periods ( id bigint not null, ts timestamp, code varchar(50), name varchar(100) );
alter table periods add constraint PK_PERIOD primary key (id);
insert into periods(id, code, name) values(1, '111', '222');
VB part:
Dim conn As New ADODB.Connection conn.CursorLocation = adUseClient ' i have also tried server conn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ACC;Data Source=ENDY"
Dim rs1 As New ADODB.Recordset, rs2 As New ADODB.Recordset rs1.Open "select * from periods", conn, _ adOpenStatic, adLockBatchOptimistic ' i have also tried keyset rs2.Open "select * from periods", conn, _ adOpenStatic, adLockBatchOptimistic
rs1.Fields("code") = "abc" ' old: 111 new: abc rs2.Fields("name") = "def" ' old: 222 new: def
rs1.UpdateBatch ' code: abc name: 222 rs2.UpdateBatch ' this should fail, but it succeeded ' code: abc name: def
If timestamp doesn't work, what do you suggest I do to provide optimistic locking? ]
-------------------------------------------------
I am a bit confused. What did you expect to happen?
The behavior you show is exactly what I would expect. Calling 'UpdateBatch' forces ADO to do an Update on all pending changes and then sends the changes on to be reflected in store. There is no conflict.
It should be noted that no RDBMS supports 'concurrency'. They will go out of their way to insure 'data integrity', but to manage concurrency you have to implement a 'gatekeeper' of some kind, either within a SP, specific locks, triggers, or outside code.
-ralph
endy_tj - 31 Dec 2005 12:01 GMT > Paul Clement wrote: > > [quoted text clipped - 77 lines] > > -ralph Never mind, I got it :)
Just modify one of the recordset property, "Update Criteria": rs1.Properties("Update Criteria") to ADODB.ADCPROP_UPDATECRITERIA_ENUM.adCriteriaAllCols or ADODB.ADCPROP_UPDATECRITERIA_ENUM.adCriteriaTimeStamp
The recordset will then compare the value of all columns or the timestamp with data in db before saving, thus preventing lost update.
The default for "Update Criteria" is adCriteriaUpdCols, so if the modified columns are different, update will still succeed.
-- Endy
|
|
|