diff options
| author | Andrew Branson <andrew.branson@cern.ch> | 2014-05-12 16:55:54 +0200 |
|---|---|---|
| committer | Andrew Branson <andrew.branson@cern.ch> | 2014-05-12 16:55:54 +0200 |
| commit | 8fc06d9c794c704eed2ab8707768fc72cc677ded (patch) | |
| tree | a30d296158c22316fdcb17935c405f9958e7e606 | |
| parent | 5bf7c8dabdfc7eaf26d2748a6a05eebb1023ef83 (diff) | |
Tweak locks to hopefully avoid deadlocks a bit
| -rw-r--r-- | src/main/java/com/c2kernel/persistency/TransactionManager.java | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/src/main/java/com/c2kernel/persistency/TransactionManager.java b/src/main/java/com/c2kernel/persistency/TransactionManager.java index 86e8199..d966eec 100644 --- a/src/main/java/com/c2kernel/persistency/TransactionManager.java +++ b/src/main/java/com/c2kernel/persistency/TransactionManager.java @@ -63,16 +63,14 @@ public class TransactionManager { Integer sysKeyIntObj = new Integer(sysKey);
// check to see if the locker has been modifying this cluster
- synchronized(locks) {
- if (locks.containsKey(sysKeyIntObj) && locks.get(sysKeyIntObj).equals(locker)) {
- ArrayList<TransactionEntry> lockerTransaction = pendingTransactions.get(locker);
- for (TransactionEntry thisEntry : lockerTransaction) {
- if (sysKey == thisEntry.sysKey.intValue() && path.equals(thisEntry.getPath())) {
- if (thisEntry.obj == null)
- throw new ClusterStorageException("ClusterStorageManager.get() - Cluster " + path + " has been deleted in " + sysKey +
- " but not yet committed");
- return thisEntry.obj;
- }
+ if (locks.containsKey(sysKeyIntObj) && locks.get(sysKeyIntObj).equals(locker)) {
+ ArrayList<TransactionEntry> lockerTransaction = pendingTransactions.get(locker);
+ for (TransactionEntry thisEntry : lockerTransaction) {
+ if (sysKey == thisEntry.sysKey.intValue() && path.equals(thisEntry.getPath())) {
+ if (thisEntry.obj == null)
+ throw new ClusterStorageException("ClusterStorageManager.get() - Cluster " + path + " has been deleted in " + sysKey +
+ " but not yet committed");
+ return thisEntry.obj;
}
}
}
@@ -85,6 +83,7 @@ public class TransactionManager { */
public void put(int sysKey, C2KLocalObject obj, Object locker) throws ClusterStorageException {
Integer sysKeyIntObj = new Integer(sysKey);
+ Object tempLocker = null;
ArrayList<TransactionEntry> lockerTransaction;
String path = ClusterStorage.getPath(obj);
@@ -99,28 +98,35 @@ public class TransactionManager { throw new ClusterStorageException("ClusterStorageManager.get() - Access denied: Object " + sysKeyIntObj +
" has been locked for writing by " + thisLocker);
}
- else { // either we are the locker, or there is no locker
- if (locker == null) { // non-locking put/delete
- storage.put(sysKeyIntObj, obj);
- return;
+ else { // no locks for this item
+ if (locker == null) { // lock the item until the non-transactional put is complete :/
+ tempLocker = new Object();
+ locks.put(sysKeyIntObj, tempLocker);
+ lockerTransaction = null;
}
- else {// initialise the transaction
+ else { // initialise the transaction
locks.put(sysKeyIntObj, locker);
lockerTransaction = new ArrayList<TransactionEntry>();
pendingTransactions.put(locker, lockerTransaction);
}
}
-
- // create the new entry in the transaction table
- TransactionEntry newEntry = new TransactionEntry(sysKeyIntObj, path, obj);
- /* equals() in TransactionEntry only compares sysKey and path, so we can use
- * contains() in ArrayList to looks for preexisting entries for this cluster
- * and overwrite them.
- */
- if (lockerTransaction.contains(newEntry))
- lockerTransaction.remove(newEntry);
- lockerTransaction.add(newEntry);
}
+
+ if (tempLocker != null) { // non-locking put/delete
+ storage.put(sysKeyIntObj, obj);
+ locks.remove(sysKeyIntObj);
+ return;
+ }
+
+ // create the new entry in the transaction table
+ TransactionEntry newEntry = new TransactionEntry(sysKeyIntObj, path, obj);
+ /* equals() in TransactionEntry only compares sysKey and path, so we can use
+ * contains() in ArrayList to looks for preexisting entries for this cluster
+ * and overwrite them.
+ */
+ if (lockerTransaction.contains(newEntry))
+ lockerTransaction.remove(newEntry);
+ lockerTransaction.add(newEntry);
}
/** Public delete method. Uses the put method, with null as the object value.
@@ -128,6 +134,7 @@ public class TransactionManager { public void remove(int sysKey, String path, Object locker) throws ClusterStorageException {
Integer sysKeyIntObj = new Integer(sysKey);
ArrayList<TransactionEntry> lockerTransaction;
+ Object tempLocker = null;
synchronized(locks) {
// look to see if this object is already locked
if (locks.containsKey(sysKeyIntObj)) {
@@ -141,8 +148,9 @@ public class TransactionManager { }
else { // either we are the locker, or there is no locker
if (locker == null) { // non-locking put/delete
- storage.remove(sysKeyIntObj, path);
- return;
+ tempLocker = new Object();
+ locks.put(sysKeyIntObj, tempLocker);
+ lockerTransaction = null;
}
else {// initialise the transaction
locks.put(sysKeyIntObj, locker);
@@ -150,17 +158,24 @@ public class TransactionManager { pendingTransactions.put(locker, lockerTransaction);
}
}
-
- // create the new entry in the transaction table
- TransactionEntry newEntry = new TransactionEntry(sysKeyIntObj, path, null);
- /* equals() in TransactionEntry only compares sysKey and path, so we can use
- * contains() in ArrayList to looks for preexisting entries for this cluster
- * and overwrite them.
- */
- if (lockerTransaction.contains(newEntry))
- lockerTransaction.remove(newEntry);
- lockerTransaction.add(newEntry);
}
+
+ if (tempLocker != null) {
+ storage.remove(sysKeyIntObj, path);
+ locks.remove(sysKeyIntObj);
+ return;
+ }
+
+ // create the new entry in the transaction table
+ TransactionEntry newEntry = new TransactionEntry(sysKeyIntObj, path, null);
+ /* equals() in TransactionEntry only compares sysKey and path, so we can use
+ * contains() in ArrayList to looks for preexisting entries for this cluster
+ * and overwrite them.
+ */
+ if (lockerTransaction.contains(newEntry))
+ lockerTransaction.remove(newEntry);
+ lockerTransaction.add(newEntry);
+
}
/**
|
