Optimistic or Pessimistic

Concurrency comes with overhead of locking problem. Oracle uses pessimistic locking on default. SELECT * FOR UPDATE locks related rows for possible writes, because SELECT * FOR UPDATE means "I will write to these rows, do not touch them". OK, here comes question, why a writer do really block other writes? Because a writer altering the data for a purpose. If this purpose will be broken down in case of write operation, data inconsistency will occur. This is not only an ACID versus situation also your business logic will corrupt.
As we said FOR UPDATE is pessimistic. Consider a web page selling used cars. Customers want to a list of cars related to some searh criters. Is it good to show this list with FOR UPDATE? It is possible but it is not a realistic solution, we may use stateful session beans or another middle layer session solution. But FOR UPDATE will defeat concurrency (in this specific example, I do not say never use FOR UPDATE)
We must not use FOR UPDATE and we must overcome lost update problem. We will use optimistic locking. We will add a version column to each car in our inventory, when a user comes with a request of 'buy this car, it is ID is ...' we will check version column. If version is higher than our version: this means "this car has just sold when you are looking to list". Nice solution, widely used in many persistency tecnology.
Oracle comes with an other solution "rowdependencies". Each row will have a extra place to declare ROW_SCN (SCN is a number, an internal clock, in case of commit SCN increases). In absence of "rowdependencies" Oracle uses a place in datablock to declare datablock_SCN.

Here is a demo:

ert@ORCL> create table t_no_rowdep as select * from all_objects where rownum < 5;
ert@ORCL> create table t_row_dep rowdependencies as select * from t_no_rowdep;

We created 2 same-data table

ert@ORCL> select ora_rowscn, dbms_rowid.rowid_block_number(rowid) bn, object_nam e from t_row_dep;

ORA_ROWSCN BN OBJECT_NAME
---------- ---------- ------------------------------
899479 18780 ICOL$
899479 18780 I_USER1
899479 18780 CON$
899479 18780 UNDO$

ert@ORCL> select ora_rowscn, dbms_rowid.rowid_block_number(rowid) bn, object_nam e from t_no_rowdep;

ORA_ROWSCN BN OBJECT_NAME
---------- ---------- ------------------------------
899426 18772 ICOL$
899426 18772 I_USER1
899426 18772 CON$
899426 18772 UNDO$

Each of them is small enough to fit in a datablock. Now we update only one row.

ert@ORCL> update t_no_rowdep set object_name = reverse(object_name) where object_name = 'CON$';

1 row updated.

ert@ORCL> commit;

Commit complete.

ert@ORCL> select ora_rowscn, dbms_rowid.rowid_block_number(rowid) bn, object_name from t_no_rowdep;

ORA_ROWSCN BN OBJECT_NAME
---------- ---------- ------------------------------
899625 18772 ICOL$
899625 18772 I_USER1
899625 18772 $NOC
899625 18772 UNDO$

All rows seems to have updated SCN. No, not all of them updated. We are not using rowdependencies option. Each datablock have one physical place to declare last SCN of datablock.

ert@ORCL> update t_row_dep set object_name = reverse(object_name) where object_name = 'CON$';

1 row updated.

ert@ORCL> commit;

Commit complete.

ert@ORCL> select ora_rowscn, dbms_rowid.rowid_block_number(rowid) bn, object_name from t_row_dep;

ORA_ROWSCN BN OBJECT_NAME
---------- ---------- ------------------------------
899479 18780 ICOL$
899479 18780 I_USER1
899666 18780 $NOC
899479 18780 UNDO$

One row’s ORA_ROWSCN updated, as we need. It is your option to use ORA_ROWSCN with rowdependencies option to implement optimistic locking. So “ORA_ROWSCN can be set to be unique for each row of a table by ROWDEPENDENCIES” is not a myth…

2 Comments

  1. okike
    Posted September 6, 2008 at 1:30 am | Permalink

    How can I modify my current tables to have rowdependencies? I cannot drop and re-creat them. Is there any script I can use? Thanks.

  2. Posted September 6, 2008 at 8:54 am | Permalink

    Hi Okike
    Unfortunately you can not alter existing tables to have row dependencies. Indeed, it is very logical, in a datablock all rows have the same SCN which is false for some rows in that datablock. It is not nice to accept false SCN as a right SCN


Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*