JPG
JPG

Reputation: 545

table update locking from vbscript

From a table like this:

ID  SEQUENCE
1    1

I want to increment the sequence value each time the table is accessed. So far I came up with this vbscript:

Dim Result
On Error Resume Next
Result = GetSequential()
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.CreateTextFile("result_" & Result & ".txt", False)
if err.Number <> 0 then
   MsgBox err.Description & " (" & Err.Number & "): " & Result
end if
on error goto 0
wscript.echo "Next value: " & Result

Function GetSequential()
Dim cn, rs
Dim Sequential

Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.connectionstring = "Driver={MySQL ODBC 5.2a Driver};Server=172.16.0.130;Database=testautostore;User=root;Password=aquilae"
cn.Open

Dim SqlCount
SqlCount = "select count(*) from counter where ID='1'"
rs.Open SqlCount, cn, adOpenStatic

If rs(0) = "1" Then 
    wscript.echo "Updating record..."
    Dim SqlUpdate
    SqlUpdate = "update counter set SEQUENCE=SEQUENCE + 1 where ID='1'"
    cn.Execute SqlUpdate

    Dim SqlSelect
    SqlSelect = "select SEQUENCE from counter where ID='1'"
    rs.Close
    rs.Open SqlSelect, cn, adOpenStatic

    Sequential = rs(0)
    wscript.echo "Result: " & Sequential
End if

rs.Close
Set rs = Nothing
cn.Close

GetSequential = Sequential
End Function

This works fine when run individually:

cscript testsequence.vbs

but when running it several times simultaneously then is not guaranteed to get a unique sequence number. This is apparent when launching a batch file like this:

for /l %%x in (1, 1, 25) do start cscript testsequence.vbs

which produces exception failures when creating the result_?.txt files as a result of returning the same sequence value (File already exists).

So the question is how can I lock the table update operation?

Thanks in advance.

Upvotes: 0

Views: 1167

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200273

You seem to assume that the update and read in your script will be atomic:

  • process A updates sequence
  • process A reads sequence
  • process B updates sequence
  • process B reads sequence

MySQL, however, has autocommit enabled by default, so each statement is run by itself, and queries from concurrent processes may become intermingled:

  • process A updates sequence
  • process B updates sequence
  • process B reads sequence
  • process A reads sequence

That way A and B will read the same value, although both processes incremented it.

You need to put your statements in a transaction and use an appropriate isolation level.

Upvotes: 1

Related Questions