Thanks for testing this out !
I'll try and setup a testcase against Oracle. However, it won't be for today I'm afraid. :-( I'll do my best.
Two questions though.
- In your scenario you explicitely write "...and flushes the session". Do you mean that within your code you programmatically flush the session ?
- Do you think the behaviour will be the same if these transactions would run within different hibernate apps (that accessi the same db and rows) ?
Coming back to Oracle. The following part still worries me:
Quote:
Default Locking for INSERT, UPDATE, DELETE, and SELECT ... FOR UPDATE
The locking characteristics of INSERT, UPDATE, DELETE, and SELECT ... FOR UPDATE statements are as follows:
The transaction that contains a DML statement acquires exclusive row locks on the rows modified by the statement. Other transactions cannot update or delete the locked rows until the locking transaction either commits or rolls back.
The transaction that contains a DML statement does not need to acquire row locks on any rows selected by a subquery or an implicit query, such as a query in a WHERE clause. A subquery or implicit query in a DML statement is guaranteed to be consistent as of the start of the query and does not see the effects of the DML statement it is part of.
A query in a transaction can see the changes made by previous DML statements in the same transaction, but cannot see the changes of other transactions begun after its own transaction.
In addition to the necessary exclusive row locks, a transaction that contains a DML statement acquires at least a row exclusive table lock on the table that contains the affected rows. If the containing transaction already holds a share, share row exclusive, or exclusive table lock for that table, the row exclusive table lock is not acquired. If the containing transaction already holds a row share table lock, Oracle Database automatically converts this lock to a row exclusive table lock.
As I understand the above piece of text, when I execute (pseudocode) an
update Person set version=new version number, ... where personSK='x' and version = old version number. The where part, which is an implicit query, will execute and won't block other readers. So if I've got two txns trying to update that same Person, they both read '0' as the current version number in the database, both increment the version to '1' and then commit ...
Does that make sense ?