Lock Management with Dynamic Buffers

Posted by chris_riddell on 12-Apr-2017 09:22

There is lots of documentation and discussion regarding how the scope of static buffers, relative to transaction scope, affects lock management. I have not been able to find any documentation or discussion of how this works with dynamic buffers. Based on experimentation I've found that downgrading of locks works exactly the same; when a transaction ends the lock downgrades from EXCLUSIVE to SHARE. However, from what I can tell, as long as there is a record in the buffer it will behave like a free reference and that SHARE-LOCK will be retained. Is there any way to strongly scope a dynamic buffer to a block? Or some other method of releasing, rather than downgrading, that EXCLUSIVE-LOCK?

I'm just looking for best practices or suggestions, or a pointer to documentation on the subject if someone knows where it can be found.

Thanks,

Chris

All Replies

Posted by Tim Kuehn on 12-Apr-2017 09:28

bufferHandle:buffer-release() will release the record, and the record's lock will go to no-lock at the end of the TX.

bufferHandle:find-current(no-lock) will mark the record's lock to be released at the end of the TX.

or you could delete the object which will mark the record's lock to be released at the end of the TX.

You can also put the delete object in a finally block at the end of the routine - like so:

FINALLY:

delete object bufferObject.

END FINALLY.

Posted by Peter Judge on 12-Apr-2017 09:30

You should always use explicit transaction blocks with dynamic buffers.
You should also use the BUFFER-RELEASE() method on the buffer after update.
 
One trick with dynamic buffers is that it’s not immediately obvious how to create a *separate* named buffer.
 
This does NOT
CREATE BUFFER hBuffer FOR TABLE customer.
 
This DOES
CREATE BUFFER hBuffer FOR TABLE customer BUFFER-NAME “localCustomer”.  
 
Between those three things you should be able to adequately control record and transaction scopes with dynamic buffers.
 

Posted by chris_riddell on 12-Apr-2017 09:37

Thanks for the quick replies and suggestions!

You both suggest using BUFFER-RELEASE() and I've read quite a few threads that include discussions of "RELEASE buffer" being a red flag. Are there any similar concerns with using BUFFER-RELEASE()? Maybe it's just that the two are completely different in the sense that "RELEASE buffer" is a strong sign that the record scope is unnecessarily large and the same controls don't exist for dynamic buffers?

Any thoughts on that?

Posted by Tim Kuehn on 12-Apr-2017 09:44

The issue with RELEASE is the mistaken belief that this statement clears the lock, even when you're in the middle of a TX.  That's not the case - a locked record in a TX will remain locked until the TX ends regardless of whether the record's in scope or not.

In this context, BUFFER-RELEASE() will kick the record out of scope, and it'll go to NO-LOCK after the TX ends. (And not before. :))

Posted by Peter Judge on 12-Apr-2017 09:46

It’s mainly because for dynamic buffers the rcode doesn’t by default contain the record/transaction scopes . So you have to manage it more closely yourself.
 

Posted by Fernando Souza on 12-Apr-2017 10:02

Regarding " BUFFER-RELEASE() will kick the record out of scope, and it'll go to NO-LOCK after the TX ends".

The record is out of scope and it will not be in the buffer anymore, so it does not go to NO-LOCK. It just is not in scope anymore at all, as long as there is no other buffer with that same record in scope. What will happen at the end of the transaction is that the lock will be released instead of being downgraded.

Posted by Tim Kuehn on 12-Apr-2017 10:09

Fernando - I do believe you're agreeing with me....

This thread is closed