|Title: ||When I use DBLOCK/DBUNLOCK inside a transaction a deadlock happens|
|Author: ||Roland Genske <email@example.com>|
Q: Whenever I use DBLOCK/DBUNLOCK inside a transaction a deadlock happens as soon as a second session executes the same program. Is this normal?
A: Unfortunately, it is as long as you introduce transactions without redesigning your DBLOCK strategy. The problem which happens is:
This can be worked-around in your application if you do all relevant DBLOCKs *before* you DBBEGIN the transaction. You might also consider that any DBLOCK is not necessary anymore since the transaction itself provides its own locking (see above). This depends on your application.
- As soon as session 1 updates any record inside a transaction, this record gets locked implicitely until the transaction is committed or rolled-back.
- Now, session 2 does a DBLOCK and DBUPDATE. This DBUPDATE blocks because the affected record was previously updated by session 1 and session 1 has not yet committed its transaction. As a consequence, session 2 does not get the chance to DBUNLOCK.
- Next, session 1 does a DBLOCK and blocks because session 2 did not yet DBUNLOCK --> a deadlock occurs.
A solution to this problem is available with Eloquence A.06.30: With the A.06.30 eloqdb6 database server,
any DBUNLOCK inside a transaction is delayed until the transaction is committed or rolled-back. In the example above, this would cause the first DBLOCK in session 2 to block until session 1 commits its transaction.