transactions/releasing records

jmac13

Member
Hi All I'm using open edge 10.2b

I'm running a procedure within a trigger for a button which is in a .p. this procedure runs the following:

Code:
procedure logAttempts:
/* assigns the number of attempts to logon as user*/
do transaction: 
    define input parameter ipintAttempts as integer no-undo.
    define buffer bUuser for uuser.
    find bUuser where
         bUuser.uu-inits =   g-uu-inits
         exclusive-lock no-error.
    
    if avail bUuser then
        bUuser.spare-int3    =   ipintAttempts.
    release bUuser.
end.
                                  
end procedure.

It exclusive-locks the uuser record but it doesnt seem to release the record until the program is closed.
I seen that im already in a transaction with the trigger.. but i thought if i put a transaction and released the record at the end of the procedure. but it doesnt seem to do that.. what im i doing wrong.. I just want to lock one record changed it then release it.
 
For starters, the release command doesn't do what you think. In order to do what you want you need to make sure that your transaction is scoped solely the your procedure above. If it is already a transaction at this point (MESSAGE TRANSACTION VIEW-AS ALERT-BOX), then the record will not be released until the bigger transaction is finished.
 
yeah i thought as much..just not quite sure why my button choose trigger is in a transaction.. got to admit im not very hot on transactions.. I guess have to try and work out why its in a transaction.. not very clear in a .p
 
It could be a transaction from a calling procedure... From experience, it pays to keep your transaction scoping as tight as possible. It prevents locking issues, and unexpected behaviour, ad of course makes things more efficient.
 
yeah that could be it.. once again not my code just working with what ive got:P but yeah if i start using transaction I'll make sure i check my scope
 
IMHO: Except for rare cases calling a procedure or a function with a transaction should be a NO GO! Scattering the logic that makes up a transaction over several procedures and functions will cause more problems than it solves - at least it is not transparent.

Heavy Regards, RealHeavyDude.
 
yeah i agree RHD... looks like the transaction is in the main block... anyway not to include the triggers for the buttons or iam just stuck with it..seems the transaction is used for stuff.. great idea by someone
 
In addition to not relying on release, use COMPILE LISTING to look at the scope of the buffer. DO doesn't provide the same kind of automatic scoping that FOR and REPEAT do. Try it with DO FOR bUser putting the define parameter and buffer above the DO since they are not a part of the block.
 
what is the activity in main-block.. is there an add/update/delete in main .. may be move those actions to an internal procedure, so you move the txn scope out of main and limit it to this IP
 
Understanding transaction scope is rather simple:

Every statement that changes the database (which also includes data retrieval with an EXCLUSIVE-LOCK) can only be executed within a transaction - invokes a transaction if there is none. The transaction scope is extended to the next outer block with transaction capabilities. Blocks with automatic transaction capabilities are for example FOR EACH, REPEAT, an internal procedure or function or the procedure itself (this happens if one statement responsible for invoking a transaction is in the main block) - but not a DO block. You can always control the transaction scope manually in deliberately using the TRANSACTION keyword in the block statement.

Out of experience I know that many developers don't care or know about transaction scope, so they end up with what the compile decides - what might not be the best decision or might not suit at all. Usually this leads to transaction larger than they need be. As Tamhas said, you should check the transaction scope in adding the listing option to the compile statement and then if the transaction is larger than need be, split it up into smaller transaction making use of the TRANSACTION keyword.

Last, but not least, you should also think about buffer scope because it might not be the same as the transaction scope - which in many cases leads to unwanted behavior like SHARE-LOCKS hanging about. I find using named buffers with strong scoping one of the easiest patterns to avoid this.

Heavy Regards, RealHeavy Dude.
 
Back
Top