#At file:///C:/bzr/mysql-6.0-falcon-team/
2799 Vladislav Vaintroub 2008-08-26
Bug #38947 UPDATE threads in endless Table::fetchForUpdate loop = livelock
Problem: in Table::fetchForUpdate() there is a small possibility for a
race condition - if record belongs to transaction that is being committed
currently and the state of this transaction is still Active, but syncActive
is already unlocked. This causes re-fetch() in the fetch thread without
any wait, instead of waiting for falcon_lock_wait_timeout seconds.
This is fixed by moving signaling waiters via syncActive.unlock(),
after transaction state has changed from active to committed.
modified:
storage/falcon/Transaction.cpp
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2008-08-25 18:24:59 +0000
+++ b/storage/falcon/Transaction.cpp 2008-08-26 15:36:02 +0000
@@ -275,7 +275,6 @@ void Transaction::commit()
releaseRecordLocks();
database->serialLog->preCommit(this);
- syncActive.unlock();
@@ -303,10 +302,9 @@ void Transaction::commit()
database->flushInversion(this);
// Transfer transaction from active list to committed list, set committed state
-
- Sync syncCommitted(&transactionManager->committedTransactions.syncObject,
"Transaction::commit(2)");
Sync syncActiveTransactions(&transactionManager->activeTransactions.syncObject,
"Transaction::commit(3)");
-
+ Sync syncCommitted(&transactionManager->committedTransactions.syncObject,
"Transaction::commit(2)");
+
syncActiveTransactions.lock(Exclusive);
syncCommitted.lock(Exclusive);
@@ -316,6 +314,8 @@ void Transaction::commit()
syncCommitted.unlock();
syncActiveTransactions.unlock();
+
+ syncActive.unlock(); // signal waiting transactions
database->commit(this);