2016. 04. 28. 14:55 keltezéssel, Dimitry Sibiryakov sd@ibphoenix.com
[firebird-support] írta:
> 28.04.2016 13:41, Gabor Boros gaborboros@yahoo.com [firebird-support] wrote:
>> The message is:
>> deadlock
>> update conflicts with concurrent update
>> concurrent transaction number is ...
>
> That's an expected behavior.
Are you sure?
In the language reference for "isc_tpb_read_committed + isc_tpb_wait" I
see this: "Update conflict exceptions can never be raised by an explicit
lock statement in this TPB mode."
http://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-select.html#fblangref25-dml-with-lock
"If there is an active transaction holding ownership on this record (via explicit locking or by a normal optimistic* write-lock), the transaction attempting the explicit lock waits for the outcome of blocking transaction and when it finishes, attempts to get the lock on the record again.
Update conflict exceptions can never be raised by an explicit lock statement in this TPB mode."
As you may know, the implementation for "Select ... with lock" is to add an update to the select statement. The update doesn't change anything in the record, but does create a new version belonging to the current transaction. That new version blocks other transactions from updating the record until it is committed or rolled back. So the question really is the behavior of an update in read-committed/wait mode.
In ancient history, even in read-committed mode, Firebird blocked transactions from updating records if the most recent version was created by a concurrent transaction. At the time, we considered anyone who liked inconsistency not worth worrying much about. It was a long time ago. I thought that more recent Firebird versions allowed read-committed transactions to update records as long as the most recent version was committed. If that's right, then the documentation is right. But your tests suggest otherwise. And maybe I'm just confused. If not, I wonder if there might be some error in the back-off and retry under contention.
Here's what happens during a wait (be patient, it's a little complicated). Although Firebird doesn't lock records, it does maintain a lock table to control access to some shared resources. When a transaction starts, it takes out an exclusive lock on its own transaction id. When a transaction must wait for another transaction, it requests a shared lock on its transaction id. When a transaction ends, its lock on its transaction id is freed - however it ended. The lock management code signals the waiting transactions that they can get their lock - which they don't particularly want - they just want too wait for their predecessor's end. In the case of waiting for a potential update conflict to end, the waiting transactions re-read the record they were trying to update and check the most recent version. If read-committed transactions can update any committed record version, then the first waiting transaction sees the most recent version as committed and updates it. In the case in point, that transaction's "Select ... with lock" succeeds and all is well.
But suppose there were several transactions all trying to update the same record and all waiting for the same transaction to finish. The second and subsequent transactions could retry and see a new uncommitted version. In theory, those transactions should request a new lock on the transaction that created the new uncommited record version and wait again.
Or maybe I'm confused.
Good luck,
Ann
Posted by: Ann Harrison <aharrison@ibphoenix.com>
| Reply via web post | • | Reply to sender | • | Reply to group | • | Start a New Topic | • | Messages in this topic (8) |
Visit http://www.firebirdsql.org and click the Documentation item
on the main (top) menu. Try FAQ and other links from the left-side menu there.
Also search the knowledgebases at http://www.ibphoenix.com/resources/documents/
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
No comments:
Post a Comment