CacheSetUseExclusive

  Previous topic Next topic  

CacheSetUseExclusive( nMode, hConnection ) -> nPrevMode

The function controls the behavior of USE ... EXCLUSIVE command. By default this command is implemented as per DBFCDX standards. Internally CachéRDD is managing this behavior via a special lock.

In production I encounted a peculiar problem with Caché when a large number of locks were causing a deadlock under certain situations. I refered the matter with Intersystems' support, who, after long tests and discussions, reached to the conclusion that the way CachéRDD is handling locks does not confirms to the SQL way of programming. And as Caché Database is SQL oriented by design, they cannot guarantee the smooth behavior under heavy locks scenario.

This necessitated me to devise another mechanism. But I also wanted to remain as close to DBFCDX as possible. Under network environment it is always suggested to use a table shared. As most of the tables are opened in shared mode, I decided to not use a shared lock at all. Instead I let the application open any table even if it has been used exclusive by another process. I could do so by applying a special FLOCK to simulate USE ... EXCLUSIVE behavior. This way any other process using the same table in EXCLUSIVE mode was not allowed though it was able to open the table in SHARED mode but was not allowed to make any updates to it.

This behavior is controlled through <nMode> parameter in above function, viz.,

nMode == 0 Default, as Clipper

nMode == 1 Treat Exclusive Use as Shared and apply FLock() to succeed

nMode == 2 Deny Exclusive Use and Raise an Error

So the tradeoff with <nMode> == 1 :

1.

Two processes cannot open a table in EXCLUSIVE mode.

2.

Only one process can open a table in EXCLUSIVE mode and all other processes can open in SHARED mode but cannot make any updates to it.

This function has to be called immediately after CachéAddConnection[Ex]() function. Also it should not be changed in rest of the code. Anyway, if you need exact DBFCDX behavior then do not call it all. However, suggested implementation is <nMode == 1> OR <nMode == 2> if you can live without opening a table in EXCLUSIVE mode.

I may remind you that EXCLUSIVE/SHARED mode has no effect on external processes if <nMode == 0>. But if <nMode == 1> then external processes will not be allowed to update it though they will be able to read its contents