diff options
author | Brian S. O'Neill <bronee@gmail.com> | 2008-08-22 15:31:51 +0000 |
---|---|---|
committer | Brian S. O'Neill <bronee@gmail.com> | 2008-08-22 15:31:51 +0000 |
commit | bdb0100ef66e6cb9ec30120687cdec44f9b61840 (patch) | |
tree | 306ad2d542547f65e0848cbb78aa1613339c0aff /src/main/java/com/amazon/carbonado/repo/map | |
parent | 2d19f5e828adc55b238e4dff64ca62868c1bcc83 (diff) |
Fixed map repository deadlock with countAll and truncate when in transaction.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/repo/map')
-rw-r--r-- | src/main/java/com/amazon/carbonado/repo/map/MapStorage.java | 48 |
1 files changed, 31 insertions, 17 deletions
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<S extends Storable> public void truncate() throws PersistException {
try {
- Object locker = mRepo.localTransactionScope().getTxn();
- if (locker == null) {
- locker = Thread.currentThread();
- }
- doLockForWrite(locker);
- try {
+ TransactionScope<MapTransaction> 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<S extends Storable> 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<MapTransaction> 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;
|