From bdb0100ef66e6cb9ec30120687cdec44f9b61840 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Fri, 22 Aug 2008 15:31:51 +0000 Subject: Fixed map repository deadlock with countAll and truncate when in transaction. --- .../com/amazon/carbonado/repo/map/MapStorage.java | 48 ++++++++++++++-------- 1 file changed, 31 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/main/java/com/amazon/carbonado/repo/map/MapStorage.java b/src/main/java/com/amazon/carbonado/repo/map/MapStorage.java index e700bd7..284a960 100644 --- a/src/main/java/com/amazon/carbonado/repo/map/MapStorage.java +++ b/src/main/java/com/amazon/carbonado/repo/map/MapStorage.java @@ -200,15 +200,19 @@ class MapStorage public void truncate() throws PersistException { try { - Object locker = mRepo.localTransactionScope().getTxn(); - if (locker == null) { - locker = Thread.currentThread(); - } - doLockForWrite(locker); - try { + TransactionScope scope = mRepo.localTransactionScope(); + MapTransaction txn = scope.getTxn(); + if (txn == null) { + doLockForWrite(scope); + try { + mMap.clear(); + } finally { + mLock.unlockFromWrite(scope); + } + } else { + txn.lockForWrite(mLock); + // Non-transactional truncate. (is not added to undo log) mMap.clear(); - } finally { - mLock.unlockFromWrite(locker); } } catch (PersistException e) { throw e; @@ -537,15 +541,25 @@ class MapStorage public long countAll() throws FetchException { try { - Object locker = mRepo.localTransactionScope().getTxn(); - if (locker == null) { - locker = Thread.currentThread(); - } - doLockForRead(locker); - try { - return mMap.size(); - } finally { - mLock.unlockFromRead(locker); + TransactionScope scope = mRepo.localTransactionScope(); + MapTransaction txn = scope.getTxn(); + if (txn == null) { + doLockForRead(scope); + try { + return mMap.size(); + } finally { + mLock.unlockFromRead(scope); + } + } else { + // Since lock is so coarse, all reads in transaction scope are + // upgrade to avoid deadlocks. + final boolean isForUpdate = scope.isForUpdate(); + txn.lockForUpgrade(mLock, isForUpdate); + try { + return mMap.size(); + } finally { + txn.unlockFromUpgrade(mLock, isForUpdate); + } } } catch (FetchException e) { throw e; -- cgit v1.2.3