mab <barborak (AT) mode20 (DOT) com> writes:
Quote:
I have multiple databases in a single file. In one transaction, I am
updating some of those databases and in another I am opening a
different database though one in the same file. I am doing this in a
single thread and am getting a self deadlock because it appears that
the databases overlap on a page in the file. A snippet from db_stat
shows this: |
As a rule of thumb, no single thread of control should have multiple
independent lockers in use at any given time. If a thread does so and
one of the lockers blocks another, the DB library cannot tell that a
deadlock has occured: it doesn't know that the blocking locker won't be
moved forward in another thread or process. Yes, you _may_ be able to
get away with this in particular circumstances, but doing so a fragile
design.
Since independent transactions are independent lockers, having two
transactions open in a single thread is only safe if one is a child
transaction of the other, as the locks held by a parent won't block the
child. Note that even working in two sibling transactions can result in
self deadlock, as siblings _do_ conflict with each other.
This is described in the Sleepycat Programmer's manual, chapter 14 (The
Locking Subsystem), section 12 (Berkeley DB Transactional Data Store
locking conventions). Note particularly the paragraph that starts "This
has important implications."
So, there are three solutions:
1) do all the operations in a single transaction,
2) commit or abort the pending transaction before starting a new one, or
3) put the transactions in different threads.
Which choice is best for your application depends on why you're using
transactions they way you currently are.
Philip Guenther