Note that there are some explanatory texts on larger screens.

plurals
  1. POOracle DB lock table use
    primarykey
    data
    text
    <p>Recently I had a task, according to which, I needed to have a specific lock functionality. The specific was due to:</p> <blockquote> <ol> <li>Transaction that was updating table was distributed, so I had no controll over it, </li> <li>During the day thousands non blocking transactions must be supported simultaniously, lets call them 'general' operations,</li> <li>Each 'general' operation updated rows on specific 'branch' ("LDN","NY","LA" ...),</li> <li>Once a day there is a 'master' operation for each branch, which happen spanteniously, on different branches, <ol> <li>During 'master' operation no 'general' operations on that branch can happen.</li> <li>When 'master' operation start it must wait for current 'general' operation on the provided branch completion, which were in the system before 'master' operation arrived.</li> <li>Durring 'master' processing on a specific branch, all other branches can be updated.</li> </ol></li> </ol> </blockquote> <p>In order to archive this, I created Oracle DB specific table</p> <pre><code>create table BRANCH_LOCK( BRANCH VARCHAR2(10), FLAG VARCHAR2(1), CONSTRAINT "PK_BRANCH_LOCK" PRIMARY KEY ("BRANCH") ) </code></pre> <p>The following functionality for different operations was supported:</p> <p>For 'general' operations:</p> <blockquote> <pre><code>1. In the same XA transaction each operation locks BRANCH_LOCK table in SHARE mode, 2. After locking it checks FLAG, on updated branch, 1. If flag is 'Y', that means that currently 'master' operation is in progess, so Exception is thrown, and no further processing is done; 2. If flag is 'N' than everything is OK, and general processing is done; </code></pre> </blockquote> <p>For 'master' operation:</p> <blockquote> <ol> <li>When 'master' operation comes I start separate transaction which: <ol> <li>Lock BRANCH_LOCK table in EXCLUSIVE mode, which transaction can not acquire while there is SHARE mode LOCK on this table in a different transaction (This way, I guarantee that 'master' operation would start after all current 'general' operation finish, although it waits for transactions on all branches to finish, not only specified one),</li> <li>Sets flag for the branch to 'Y' (This way, I guarantee that there would be no 'general' transactions while 'master' operation processing),</li> </ol></li> <li>In incoming transaction I change a Flag in the table to 'N', so after it commits BRANCH_LOG table will have appropriate value in FLAG column, and system would be able to process 'general' operations again.</li> </ol> </blockquote> <p>This has not gone in production yet, So I wonder is there a better solution for this, and are there any more drawbacks besides described one?</p> <p>Some updates, which I did not mention:</p> <ol> <li>'Master' operation works on results of 'general' operations, So it is vital, that no 'general' operation get lost, durring the 'master' processing, so this why current 'general' operation must finish, before master operation start processing.</li> <li>Multiple 'general' operations on the same branch happen every second, arround 3'000 operations per second,</li> <li>Only one 'master' operation for the branch can happen, multiple 'master' operations on different branches can be processed at the same time.</li> </ol>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload