Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Vo2Ado and multiuser environment locks

97 views
Skip to first unread message

Sebastián BASSANO

unread,
Aug 26, 2022, 7:58:48 AM8/26/22
to
Hi, i have an operation that needs to authorize a document via a third party web server and then update a table on my database. The process works fine but i need to add multiuser support, means that when an user is doing that operation the other users can't. I work with Vo2Ado.
Today the code (simplified, without the BEGIN SEQUENCE/RECOVER USING code block) is similar to this:


// Get third party authorization code via web service
cAuthorizationCode:= oWebService:GetAuthorization(...)

// Update table
oConnection:BeginTrans()
cCommand:= "UPDATE document SET authorizationCode = " + cAuthorizationCode + " WHERE (id = " + NTrim(cId) + ")"
oConnection:Execute(cCommand, @liAffectedRecords, NIL)
if (liAffectedRecords > 0)
oConnection:CommitTrans()
ELSE
oConnection:Rollback()
ENDIF


This code doesn't work on multiuser environment because the record lock is applied on line:

oConnection:Execute(cCommand, @liAffectedRecords, NIL)

and at this point two or more users could get more authorization codes because the third party web service don't receive any local information to test if the authorization code already exists. I need to lock the record before start the communication with web service.
I understand that i can't lock records explicitly as with DbServer:LockCurrentRecord ¿is this correct?
If i'm correct ¿what would be the correct way to achieve this?

Maybe something this? I'm not convinced...


oConnection:BeginTrans()

// Force to lock the record updating value with the actual value
cCommand:= "UPDATE document SET authorizationCode = authorizationCode + " WHERE (id = " + NTrim(cId) + ")"
oConnection:Execute(cCommand, @liAffectedRecords, NIL)

if (liAffectedRecords > 0)
// Get third party authorization code via web service
cAuthorizationCode:= oWebService:GetAuthorization(...)

// Update table
cCommand:= "UPDATE document SET authorizationCode = " + cAuthorizationCode + " WHERE (id = " + NTrim(cId) + ")"
oConnection:Execute(cCommand, @liAffectedRecords, NIL)
oConnection:CommitTrans()
ELSE
oConnection:Rollback()
ENDIF


I appreciate some help.
Regards.

Sebastián

Jamal

unread,
Aug 26, 2022, 1:57:55 PM8/26/22
to
Try adding:

WITH (ROWLOCK)

to your SQL UPDATE statement.

"UPDATE document SET authorizationCode = " + cAuthorizationCode + " WITH
(ROWLOCK) WHERE (id = " + NTrim(cId) + ")"

Jamal

Sebastián BASSANO

unread,
Aug 26, 2022, 2:10:44 PM8/26/22
to
Hi Jamal, thanks for your response.
the problem is that when a user reaches that line of code in the third party web service an authorization code has already been managed.

An example:

Time1 - User 1 open associated dialog to get authorization code on PC1
Time2 - User 2 open associated dialog to get authorization code on PC2
Time3 - User 1 get authorization code (before this i have to lock to avoid that other used get authorization code)
Time4 - User 1 update authorizarion code on database
Time5 - User 2 get authorization code
Time6 - User 2 update authorizarion code on database

I hope my problem is better understood, English is not my native language.
Regards.

Jamal

unread,
Aug 26, 2022, 3:11:19 PM8/26/22
to
May be you can use the same approach when you SELECT the row and before
you get the authorization, then update the row.

If this does not work, try creating another table that indicates that
you're in an update process and handle your update process accordingly.

Jamal

Sebastián BASSANO

unread,
Aug 26, 2022, 3:16:15 PM8/26/22
to
Thanks, i will try in that way!

JohnMartens

unread,
Aug 26, 2022, 3:23:42 PM8/26/22
to
Hi Sebastian,

Do you NEED to have two users to use the authorisation process at the
same time or do you want to avoid that thigs are messing up when users
try to use the procedure at the same time ?

If the latter is the case and you can have users wait for echt other you
could add a waiting list to a data base. If there is no waiting list,
start the process and it will run fine.
If there is a waiting list, add a user/PC specific ID to the end of the
waiting list, present the user with a waiting message and use a timer to
check once in a while if this waiting PC is now first in line and start
the auhorisation.
In this way serveral PC's/users may have small waiting time and youre
code can run free of errors

John


Op 26-8-2022 om 20:10 schreef Sebastián BASSANO:

Sebastián BASSANO

unread,
Aug 26, 2022, 3:41:12 PM8/26/22
to
Hi John, it is indeed the latter case.
I think I'm going to end up using your idea because I don't like what I was thinking of doing because it leaves the second user locked until the first user's transaction finishes (and I think with the option WITH
(ROWLOCK) option the same thing happens).
Thanks!

JohnMartens

unread,
Aug 27, 2022, 2:25:51 AM8/27/22
to
Hope it will get you to a solution
john

Op 26-8-2022 om 21:41 schreef Sebastián BASSANO:

Wolfgang Riedmann

unread,
Aug 31, 2022, 3:51:25 AM8/31/22
to
Hi Sebastián,

I would solve that in a completely different manner: I would add a
table "operations_in_progress", and when a user starts an authorization
process, I would first check if there is already a process active, and
if not, add a record there and start the authorization process.
If the authorization progress is successful, you can then write the
result to the document table, and remove the record from the in_progres
table in the same transaction.

Wolfgang


> Hi, i have an operation that needs to authorize a document via a
> third party web server and then update a table on my database. The
> process works fine but i need to add multiuser support, means that
> when an user is doing that operation the other users can't. I work
> with Vo2Ado.



--

Sebastián BASSANO

unread,
Aug 31, 2022, 8:54:58 AM8/31/22
to
Hi Wolfgang, just the way you indicate is the one I am finally implementing after reading John's answers.
Thanks!
0 new messages