summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-08-22 15:31:51 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-08-22 15:31:51 +0000
commitbdb0100ef66e6cb9ec30120687cdec44f9b61840 (patch)
tree306ad2d542547f65e0848cbb78aa1613339c0aff
parent2d19f5e828adc55b238e4dff64ca62868c1bcc83 (diff)
Fixed map repository deadlock with countAll and truncate when in transaction.
-rw-r--r--src/main/java/com/amazon/carbonado/repo/map/MapStorage.java48
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;