Hi Ron and Moshe,
Quote:
We use the C++ API wrapping of the Berkeley DB Interface, after
examining our code we discovered we get the deadlock when using the
DB_NOOVERWITE flag (with the C++ interface). |
That makes sense -- DB_NOOVERWRITE has to check whether the item
exists, which means it will lock the primary first.
Quote:
We've managed to bypass
this deadlock by avoiding the use of this flag (which is very limiting,
and narrows down our application's capabilities), but we've encountered
another deadlock now, when deleting a record from the primary DB
(similar to writing without overwriting...) |
Again, that makes sense -- DB can't generate the secondary key(s) until
it has the record from the primary that is being deleted.
Quote:
It is not clear to us, why the Berkeley DB doesn't provide atomicity
for these actions, we expect the infrastructure to be deadlock free
when performing single instructions. |
If you don't want to handle deadlock errors in your application, you
should consider the Concurrent Data Store product (open your
environment with DB_INIT_CDB instead of DB_INIT_LOCK | DB_INIT_LOG |
DB_INIT_TXN).
It implements a locking scheme similar to what you are describing
(coarse-grained read/write locking so that these operation would not
interleave). It is deadlock free. When used with secondaries, you
should also set the DB_CDB_ALLDB flag on the environment.
The major disadvantage of CDS is that it does not provide logging and
recovery, so you need to verify database integrity after application or
process failures, and potentially restore data from backups.
Regards,
Michael.