We have about 1000 client machines that need regular processing performed, which is done by a bank of 20 servers.
We have a table that lists all the client ids, a flag that indicates whether they need processing, and field indicating which server is currently working with that client.
A client can only be connected to by one server at a time, so I wrote the following logic so that the servers regularly poll the client table to look for the ones that need processing, and then "lock" that record by populating the server field.
This logic works 99% of the time. But for some strange reason, a couple times a week we will have an error where 2 servers start trying to work on the same client at once.
I can't reproduce it, and the logic seems correct to me (obviously I wrote it!).
If you could take a look at this and tell me if you see how 2 servers could attempt to work on the same client at once, I would appreciate it.
Each server program has a timer event that fires every minute to run this code and check for possible processing to perform.
Table has 3 fields:
client_id - an integer contain the id's for each client
process_flag - an integer indicating a process needs performed (zero means nothing needs done)
locked_by_server - a string containing the machine name of the server working with that client
The code is written in VB6 using ADO to connect to a SQL server, but the logical is all T-SQL based, so I figured the folks in this board might have some good ideas.
Thanks for any suggestions you have.
We have a table that lists all the client ids, a flag that indicates whether they need processing, and field indicating which server is currently working with that client.
A client can only be connected to by one server at a time, so I wrote the following logic so that the servers regularly poll the client table to look for the ones that need processing, and then "lock" that record by populating the server field.
This logic works 99% of the time. But for some strange reason, a couple times a week we will have an error where 2 servers start trying to work on the same client at once.
I can't reproduce it, and the logic seems correct to me (obviously I wrote it!).
If you could take a look at this and tell me if you see how 2 servers could attempt to work on the same client at once, I would appreciate it.
Each server program has a timer event that fires every minute to run this code and check for possible processing to perform.
Table has 3 fields:
client_id - an integer contain the id's for each client
process_flag - an integer indicating a process needs performed (zero means nothing needs done)
locked_by_server - a string containing the machine name of the server working with that client
The code is written in VB6 using ADO to connect to a SQL server, but the logical is all T-SQL based, so I figured the folks in this board might have some good ideas.
Code:
MySQL = "SELECT client_id, process_flag, locked_by_server
FROM tbl_clients
WHERE process_flag <> 0
AND locked_by_server Is Null"
MyRST.Open MySQL, gDB, adOpenDynamic, adLockOptimistic
[b]'This initial query checks for clients that currently have some process to perform based on the flag, and are not currently locked by another server[/b]
Do While Not MyRST.EOF [b]'Loop for all records[/b]
MySQL = "UPDATE tbl_clients
SET locked_by_server = '" & varServerName & "'"
WHERE process_flag <> 0
AND locked_by_server Is Null"
gDB.Execute MySQL
[b]'The update query sets the server field for the
current row, but only if the flag is still on, and
another server hasn't already locked it[/b]
MySQL = "SELECT client_id
FROM tbl_clients
WHERE process_flag <> 0
AND locked_by_server = '" & varServerName & "'"
MyRSTLocked.Open MySQL, gDB, adOpenStatic, adLockOptimistic
[b]'Now we do another select to see if the update we
performed went through and we are actually the
server that got the lock[/b]
If Not MyRSTLocked.EOF Then
[b]'Perform appropriate processing
'This is where the code to connect to the client
'and perform the processing takes place
'Call process procedure passing MyRSTLocked.Fields("client_id")[/b]
MySQL = "UPDATE tbl_clients
SET process_flag = 0, locked_by_server = Null"
WHERE client_id = " & MyRSTLocked.Fields("client_id")
gDB.Execute MySQL
[b]'Now that processing is done, turn off the flag and
set the server to Null[/b]
End If
MyRSTLocked.Close [b]'Close the locked recordset[/b]
MyRST.MoveNext
Loop [b]'Go back to the next client in the original process[/b]
MyRST.Close [b]'Close the original recordset[/b]
Thanks for any suggestions you have.
