changes to release the latch of the LockTable in *finally* block
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockManager.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockManager.java
index 4e980d4..a354d2a 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockManager.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockManager.java
@@ -124,73 +124,111 @@
         JobInfo jobInfo;
         byte datasetLockMode = entityHashValue == -1 ? lockMode : lockMode == LockMode.S ? LockMode.IS : LockMode.IX;
         boolean doEscalate = false;
+        boolean caughtLockMgrLatchException = false;
 
         latchLockTable();
-        validateJob(txnContext);
+        try {
+            validateJob(txnContext);
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Requested", RequestType.LOCK, datasetId, entityHashValue, lockMode, txnContext,
-                    dLockInfo, eLockInfo);
-        }
-
-        dLockInfo = datasetResourceHT.get(datasetId);
-        jobInfo = jobHT.get(jobId);
-
-        if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-            if (!isInstant && datasetLockMode == LockMode.IS && jobInfo != null && dLockInfo != null) {
-                int escalateStatus = needEscalateFromEntityToDataset(jobInfo, dId, lockMode);
-                switch (escalateStatus) {
-                    case DO_ESCALATE:
-                        entityHashValue = -1;
-                        doEscalate = true;
-                        break;
-
-                    case ESCALATED:
-                        unlatchLockTable();
-                        return;
-
-                    default:
-                        break;
-                }
-            }
-        }
-
-        //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
-        if (dLockInfo == null || dLockInfo.isNoHolder()) {
-            if (dLockInfo == null) {
-                dLockInfo = new DatasetLockInfo(entityLockInfoManager, entityInfoManager, lockWaiterManager);
-                datasetResourceHT.put(new DatasetId(dId), dLockInfo); //datsetId obj should be created
-            }
-            entityInfo = entityInfoManager.allocate(jId, dId, entityHashValue, lockMode);
-
-            //if dataset-granule lock
-            if (entityHashValue == -1) { //-1 stands for dataset-granule
-                entityInfoManager.increaseDatasetLockCount(entityInfo);
-                dLockInfo.increaseLockCount(datasetLockMode);
-                dLockInfo.addHolder(entityInfo);
-            } else {
-                entityInfoManager.increaseDatasetLockCount(entityInfo);
-                dLockInfo.increaseLockCount(datasetLockMode);
-                //add entityLockInfo
-                eLockInfo = entityLockInfoManager.allocate();
-                dLockInfo.getEntityResourceHT().put(entityHashValue, eLockInfo);
-                entityInfoManager.increaseEntityLockCount(entityInfo);
-                entityLockInfoManager.increaseLockCount(eLockInfo, lockMode);
-                entityLockInfoManager.addHolder(eLockInfo, entityInfo);
+            if (IS_DEBUG_MODE) {
+                trackLockRequest("Requested", RequestType.LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                        dLockInfo, eLockInfo);
             }
 
-            if (jobInfo == null) {
-                jobInfo = new JobInfo(entityInfoManager, lockWaiterManager, txnContext);
-                jobHT.put(jobId, jobInfo); //jobId obj doesn't have to be created
-            }
-            jobInfo.addHoldingResource(entityInfo);
+            dLockInfo = datasetResourceHT.get(datasetId);
+            jobInfo = jobHT.get(jobId);
 
             if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-                if (!isInstant && datasetLockMode == LockMode.IS) {
-                    jobInfo.increaseDatasetISLockCount(dId);
+                if (!isInstant && datasetLockMode == LockMode.IS && jobInfo != null && dLockInfo != null) {
+                    int escalateStatus = needEscalateFromEntityToDataset(jobInfo, dId, lockMode);
+                    switch (escalateStatus) {
+                        case DO_ESCALATE:
+                            entityHashValue = -1;
+                            doEscalate = true;
+                            break;
+
+                        case ESCALATED:
+                            return;
+
+                        default:
+                            break;
+                    }
+                }
+            }
+
+            //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
+            if (dLockInfo == null || dLockInfo.isNoHolder()) {
+                if (dLockInfo == null) {
+                    dLockInfo = new DatasetLockInfo(entityLockInfoManager, entityInfoManager, lockWaiterManager);
+                    datasetResourceHT.put(new DatasetId(dId), dLockInfo); //datsetId obj should be created
+                }
+                entityInfo = entityInfoManager.allocate(jId, dId, entityHashValue, lockMode);
+
+                //if dataset-granule lock
+                if (entityHashValue == -1) { //-1 stands for dataset-granule
+                    entityInfoManager.increaseDatasetLockCount(entityInfo);
+                    dLockInfo.increaseLockCount(datasetLockMode);
+                    dLockInfo.addHolder(entityInfo);
+                } else {
+                    entityInfoManager.increaseDatasetLockCount(entityInfo);
+                    dLockInfo.increaseLockCount(datasetLockMode);
+                    //add entityLockInfo
+                    eLockInfo = entityLockInfoManager.allocate();
+                    dLockInfo.getEntityResourceHT().put(entityHashValue, eLockInfo);
+                    entityInfoManager.increaseEntityLockCount(entityInfo);
+                    entityLockInfoManager.increaseLockCount(eLockInfo, lockMode);
+                    entityLockInfoManager.addHolder(eLockInfo, entityInfo);
+                }
+
+                if (jobInfo == null) {
+                    jobInfo = new JobInfo(entityInfoManager, lockWaiterManager, txnContext);
+                    jobHT.put(jobId, jobInfo); //jobId obj doesn't have to be created
+                }
+                jobInfo.addHoldingResource(entityInfo);
+
+                if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
+                    if (!isInstant && datasetLockMode == LockMode.IS) {
+                        jobInfo.increaseDatasetISLockCount(dId);
+                        if (doEscalate) {
+                            throw new IllegalStateException(
+                                    "ESCALATE_TRHESHOLD_ENTITY_TO_DATASET should not be set to "
+                                            + ESCALATE_TRHESHOLD_ENTITY_TO_DATASET);
+                        }
+                    }
+                }
+
+                if (IS_DEBUG_MODE) {
+                    trackLockRequest("Granted", RequestType.LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                            dLockInfo, eLockInfo);
+                }
+
+                return;
+            }
+
+            //#. the datasetLockInfo exists in datasetResourceHT.
+            //1. handle dataset-granule lock
+            entityInfo = lockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext);
+
+            //2. handle entity-granule lock
+            if (entityHashValue != -1) {
+                lockEntityGranule(datasetId, entityHashValue, lockMode, entityInfo, txnContext);
+            }
+
+            if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
+                if (!isInstant) {
                     if (doEscalate) {
-                        throw new IllegalStateException("ESCALATE_TRHESHOLD_ENTITY_TO_DATASET should not be set to "
-                                + ESCALATE_TRHESHOLD_ENTITY_TO_DATASET);
+                        //jobInfo must not be null.
+                        assert jobInfo != null;
+                        jobInfo.increaseDatasetISLockCount(dId);
+                        //release pre-acquired locks
+                        releaseDatasetISLocks(jobInfo, jobId, datasetId, txnContext);
+                    } else if (datasetLockMode == LockMode.IS) {
+                        if (jobInfo == null) {
+                            jobInfo = jobHT.get(jobId);
+                            //jobInfo must not be null;
+                            assert jobInfo != null;
+                        }
+                        jobInfo.increaseDatasetISLockCount(dId);
                     }
                 }
             }
@@ -199,44 +237,18 @@
                 trackLockRequest("Granted", RequestType.LOCK, datasetId, entityHashValue, lockMode, txnContext,
                         dLockInfo, eLockInfo);
             }
-
-            unlatchLockTable();
-            return;
-        }
-
-        //#. the datasetLockInfo exists in datasetResourceHT.
-        //1. handle dataset-granule lock
-        entityInfo = lockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext);
-
-        //2. handle entity-granule lock
-        if (entityHashValue != -1) {
-            lockEntityGranule(datasetId, entityHashValue, lockMode, entityInfo, txnContext);
-        }
-
-        if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-            if (!isInstant) {
-                if (doEscalate) {
-                    //jobInfo must not be null.
-                    assert jobInfo != null;
-                    jobInfo.increaseDatasetISLockCount(dId);
-                    //release pre-acquired locks
-                    releaseDatasetISLocks(jobInfo, jobId, datasetId, txnContext);
-                } else if (datasetLockMode == LockMode.IS) {
-                    if (jobInfo == null) {
-                        jobInfo = jobHT.get(jobId);
-                        //jobInfo must not be null;
-                        assert jobInfo != null;
-                    }
-                    jobInfo.increaseDatasetISLockCount(dId);
-                }
+        } catch (Exception e) {
+            if (e instanceof LockMgrLatchHandlerException) {
+                // don't unlatch
+                caughtLockMgrLatchException = true;
+                throw new ACIDException(((LockMgrLatchHandlerException) e).getInternalException());
+            }
+        } finally {
+            if (!caughtLockMgrLatchException) {
+                unlatchLockTable();
             }
         }
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Granted", RequestType.LOCK, datasetId, entityHashValue, lockMode, txnContext, dLockInfo,
-                    eLockInfo);
-        }
-        unlatchLockTable();
         return;
     }
 
@@ -285,14 +297,9 @@
 
     private void validateJob(TransactionContext txnContext) throws ACIDException {
         if (txnContext.getTxnState() == TransactionState.ABORTED) {
-            unlatchLockTable();
             throw new ACIDException("" + txnContext.getJobId() + " is in ABORTED state.");
         } else if (txnContext.getStatus() == TransactionContext.TIMED_OUT_STATUS) {
-            try {
-                requestAbort(txnContext);
-            } finally {
-                unlatchLockTable();
-            }
+            requestAbort(txnContext);
         }
     }
 
@@ -657,127 +664,124 @@
         }
 
         latchLockTable();
-        validateJob(txnContext);
+        try {
+            validateJob(txnContext);
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Requested", RequestType.UNLOCK, datasetId, entityHashValue, (byte) 0, txnContext,
-                    dLockInfo, eLockInfo);
-        }
+            if (IS_DEBUG_MODE) {
+                trackLockRequest("Requested", RequestType.UNLOCK, datasetId, entityHashValue, (byte) 0, txnContext,
+                        dLockInfo, eLockInfo);
+            }
 
-        //find the resource to be unlocked
-        dLockInfo = datasetResourceHT.get(datasetId);
-        jobInfo = jobHT.get(jobId);
-        if (dLockInfo == null || jobInfo == null) {
-            unlatchLockTable();
-            throw new IllegalStateException("Invalid unlock request: Corresponding lock info doesn't exist.");
-        }
+            //find the resource to be unlocked
+            dLockInfo = datasetResourceHT.get(datasetId);
+            jobInfo = jobHT.get(jobId);
+            if (dLockInfo == null || jobInfo == null) {
+                throw new IllegalStateException("Invalid unlock request: Corresponding lock info doesn't exist.");
+            }
 
-        eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
+            eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
 
-        if (eLockInfo == -1) {
-            unlatchLockTable();
-            throw new IllegalStateException("Invalid unlock request: Corresponding lock info doesn't exist.");
-        }
+            if (eLockInfo == -1) {
+                throw new IllegalStateException("Invalid unlock request: Corresponding lock info doesn't exist.");
+            }
 
-        //find the corresponding entityInfo
-        entityInfo = entityLockInfoManager.findEntityInfoFromHolderList(eLockInfo, jobId.getId(), entityHashValue);
-        if (entityInfo == -1) {
-            unlatchLockTable();
-            throw new IllegalStateException("Invalid unlock request[" + jobId.getId() + "," + datasetId.getId() + ","
-                    + entityHashValue + "]: Corresponding lock info doesn't exist.");
-        }
+            //find the corresponding entityInfo
+            entityInfo = entityLockInfoManager.findEntityInfoFromHolderList(eLockInfo, jobId.getId(), entityHashValue);
+            if (entityInfo == -1) {
+                throw new IllegalStateException("Invalid unlock request[" + jobId.getId() + "," + datasetId.getId()
+                        + "," + entityHashValue + "]: Corresponding lock info doesn't exist.");
+            }
 
-        datasetLockMode = entityInfoManager.getDatasetLockMode(entityInfo) == LockMode.S ? LockMode.IS : LockMode.IX;
+            datasetLockMode = entityInfoManager.getDatasetLockMode(entityInfo) == LockMode.S ? LockMode.IS
+                    : LockMode.IX;
 
-        //decrease the corresponding count of dLockInfo/eLockInfo/entityInfo
-        dLockInfo.decreaseLockCount(datasetLockMode);
-        entityLockInfoManager.decreaseLockCount(eLockInfo, entityInfoManager.getEntityLockMode(entityInfo));
-        entityInfoManager.decreaseDatasetLockCount(entityInfo);
-        entityInfoManager.decreaseEntityLockCount(entityInfo);
+            //decrease the corresponding count of dLockInfo/eLockInfo/entityInfo
+            dLockInfo.decreaseLockCount(datasetLockMode);
+            entityLockInfoManager.decreaseLockCount(eLockInfo, entityInfoManager.getEntityLockMode(entityInfo));
+            entityInfoManager.decreaseDatasetLockCount(entityInfo);
+            entityInfoManager.decreaseEntityLockCount(entityInfo);
 
-        if (entityInfoManager.getEntityLockCount(entityInfo) == 0
-                && entityInfoManager.getDatasetLockCount(entityInfo) == 0) {
-            int threadCount = 0; //number of threads(in the same job) waiting on the same resource 
-            int waiterObjId = jobInfo.getFirstWaitingResource();
-            int waitingEntityInfo;
-            LockWaiter waiterObj;
+            if (entityInfoManager.getEntityLockCount(entityInfo) == 0
+                    && entityInfoManager.getDatasetLockCount(entityInfo) == 0) {
+                int threadCount = 0; //number of threads(in the same job) waiting on the same resource 
+                int waiterObjId = jobInfo.getFirstWaitingResource();
+                int waitingEntityInfo;
+                LockWaiter waiterObj;
 
-            //TODO
-            //This code should be taken care properly when there is a way to avoid doubling memory space for txnIds.
-            //This commit log is written here in order to avoid increasing the memory space for managing transactionIds
-            if (commitFlag) {
-                if (txnContext.getTransactionType().equals(TransactionContext.TransactionType.READ_WRITE)) {
-                    try {
-                        txnSubsystem.getLogManager().log(LogType.ENTITY_COMMIT, txnContext, datasetId.getId(),
-                                entityHashValue, -1, (byte) 0, 0, null, null, logicalLogLocator);
-                    } catch (ACIDException e) {
+                //TODO
+                //This code should be taken care properly when there is a way to avoid doubling memory space for txnIds.
+                //This commit log is written here in order to avoid increasing the memory space for managing transactionIds
+                if (commitFlag) {
+                    if (txnContext.getTransactionType().equals(TransactionContext.TransactionType.READ_WRITE)) {
                         try {
+                            txnSubsystem.getLogManager().log(LogType.ENTITY_COMMIT, txnContext, datasetId.getId(),
+                                    entityHashValue, -1, (byte) 0, 0, null, null, logicalLogLocator);
+                        } catch (ACIDException e) {
                             requestAbort(txnContext);
-                        } finally {
-                            unlatchLockTable();
                         }
                     }
+
+                    txnContext.updateLastLSNForIndexes(logicalLogLocator.getLsn());
                 }
 
-                txnContext.updateLastLSNForIndexes(logicalLogLocator.getLsn());
-            }
+                //1) wake up waiters and remove holder
+                //wake up waiters of dataset-granule lock
+                wakeUpDatasetLockWaiters(dLockInfo);
+                //wake up waiters of entity-granule lock
+                wakeUpEntityLockWaiters(eLockInfo);
+                //remove the holder from eLockInfo's holder list and remove the holding resource from jobInfo's holding resource list
+                //this can be done in the following single function call.
+                entityLockInfoManager.removeHolder(eLockInfo, entityInfo, jobInfo);
 
-            //1) wake up waiters and remove holder
-            //wake up waiters of dataset-granule lock
-            wakeUpDatasetLockWaiters(dLockInfo);
-            //wake up waiters of entity-granule lock
-            wakeUpEntityLockWaiters(eLockInfo);
-            //remove the holder from eLockInfo's holder list and remove the holding resource from jobInfo's holding resource list
-            //this can be done in the following single function call.
-            entityLockInfoManager.removeHolder(eLockInfo, entityInfo, jobInfo);
-
-            //2) if 
-            //      there is no waiting thread on the same resource (this can be checked through jobInfo)
-            //   then 
-            //      a) delete the corresponding entityInfo
-            //      b) write commit log for the unlocked resource(which is a committed txn).
-            while (waiterObjId != -1) {
-                waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
-                waitingEntityInfo = waiterObj.getEntityInfoSlot();
-                if (entityInfoManager.getDatasetId(waitingEntityInfo) == datasetId.getId()
-                        && entityInfoManager.getPKHashVal(waitingEntityInfo) == entityHashValue) {
-                    threadCount++;
-                    break;
+                //2) if 
+                //      there is no waiting thread on the same resource (this can be checked through jobInfo)
+                //   then 
+                //      a) delete the corresponding entityInfo
+                //      b) write commit log for the unlocked resource(which is a committed txn).
+                while (waiterObjId != -1) {
+                    waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
+                    waitingEntityInfo = waiterObj.getEntityInfoSlot();
+                    if (entityInfoManager.getDatasetId(waitingEntityInfo) == datasetId.getId()
+                            && entityInfoManager.getPKHashVal(waitingEntityInfo) == entityHashValue) {
+                        threadCount++;
+                        break;
+                    }
+                    waiterObjId = waiterObj.getNextWaiterObjId();
                 }
-                waiterObjId = waiterObj.getNextWaiterObjId();
-            }
-            if (threadCount == 0) {
-                if (entityInfoManager.getEntityLockMode(entityInfo) == LockMode.X) {
-                    //TODO
-                    //write a commit log for the unlocked resource
-                    //need to figure out that instantLock() also needs to write a commit log. 
+                if (threadCount == 0) {
+                    if (entityInfoManager.getEntityLockMode(entityInfo) == LockMode.X) {
+                        //TODO
+                        //write a commit log for the unlocked resource
+                        //need to figure out that instantLock() also needs to write a commit log. 
+                    }
+                    entityInfoManager.deallocate(entityInfo);
                 }
-                entityInfoManager.deallocate(entityInfo);
             }
-        }
 
-        //deallocate entityLockInfo's slot if there is no txn referring to the entityLockInfo.
-        if (entityLockInfoManager.getFirstWaiter(eLockInfo) == -1
-                && entityLockInfoManager.getLastHolder(eLockInfo) == -1
-                && entityLockInfoManager.getUpgrader(eLockInfo) == -1) {
-            dLockInfo.getEntityResourceHT().remove(entityHashValue);
-            entityLockInfoManager.deallocate(eLockInfo);
-        }
-
-        //we don't deallocate datasetLockInfo even if there is no txn referring to the datasetLockInfo
-        //since the datasetLockInfo is likely to be referred to again.
-
-        if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-            if (!isInstant && datasetLockMode == LockMode.IS) {
-                jobInfo.decreaseDatasetISLockCount(datasetId.getId());
+            //deallocate entityLockInfo's slot if there is no txn referring to the entityLockInfo.
+            if (entityLockInfoManager.getFirstWaiter(eLockInfo) == -1
+                    && entityLockInfoManager.getLastHolder(eLockInfo) == -1
+                    && entityLockInfoManager.getUpgrader(eLockInfo) == -1) {
+                dLockInfo.getEntityResourceHT().remove(entityHashValue);
+                entityLockInfoManager.deallocate(eLockInfo);
             }
-        }
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Granted", RequestType.UNLOCK, datasetId, entityHashValue, (byte) 0, txnContext,
-                    dLockInfo, eLockInfo);
+            //we don't deallocate datasetLockInfo even if there is no txn referring to the datasetLockInfo
+            //since the datasetLockInfo is likely to be referred to again.
+
+            if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
+                if (!isInstant && datasetLockMode == LockMode.IS) {
+                    jobInfo.decreaseDatasetISLockCount(datasetId.getId());
+                }
+            }
+
+            if (IS_DEBUG_MODE) {
+                trackLockRequest("Granted", RequestType.UNLOCK, datasetId, entityHashValue, (byte) 0, txnContext,
+                        dLockInfo, eLockInfo);
+            }
+        } finally {
+            unlatchLockTable();
         }
-        unlatchLockTable();
     }
 
     @Override
@@ -797,183 +801,178 @@
         JobId jobId = txnContext.getJobId();
 
         latchLockTable();
-
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Requested", RequestType.RELEASE_LOCKS, new DatasetId(0), 0, (byte) 0, txnContext,
-                    dLockInfo, eLockInfo);
-        }
-
-        JobInfo jobInfo = jobHT.get(jobId);
-        if (jobInfo == null) {
-            unlatchLockTable();
-            return;
-        }
-
-        //remove waiterObj of JobInfo 
-        //[Notice]
-        //waiterObjs may exist if aborted thread is the caller of this function.
-        //Even if there are the waiterObjs, there is no waiting thread on the objects. 
-        //If the caller of this function is an aborted thread, it is guaranteed that there is no waiting threads
-        //on the waiterObjs since when the aborted caller thread is waken up, all other waiting threads are
-        //also waken up at the same time through 'notifyAll()' call.
-        //In contrast, if the caller of this function is not an aborted thread, then there is no waiting object.
-        int waiterObjId = jobInfo.getFirstWaitingResource();
-        int nextWaiterObjId;
-        while (waiterObjId != -1) {
-            existWaiter = true;
-            waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
-            nextWaiterObjId = waiterObj.getNextWaitingResourceObjId();
-            entityInfo = waiterObj.getEntityInfoSlot();
+        try {
             if (IS_DEBUG_MODE) {
-                if (jobId.getId() != entityInfoManager.getJobId(entityInfo)) {
-                    throw new IllegalStateException("JobInfo(" + jobId + ") has diffrent Job(JID:"
-                            + entityInfoManager.getJobId(entityInfo) + "'s lock request!!!");
-                }
+                trackLockRequest("Requested", RequestType.RELEASE_LOCKS, new DatasetId(0), 0, (byte) 0, txnContext,
+                        dLockInfo, eLockInfo);
             }
 
-            //1. remove from waiter(or upgrader)'s list of dLockInfo or eLockInfo.
-            did = entityInfoManager.getDatasetId(entityInfo);
-            tempDatasetIdObj.setId(did);
-            dLockInfo = datasetResourceHT.get(tempDatasetIdObj);
-
-            if (waiterObj.isWaitingOnEntityLock()) {
-                entityHashValue = entityInfoManager.getPKHashVal(entityInfo);
-                eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
-                if (waiterObj.isWaiter()) {
-                    entityLockInfoManager.removeWaiter(eLockInfo, waiterObjId);
-                } else {
-                    entityLockInfoManager.removeUpgrader(eLockInfo, waiterObjId);
-                }
-            } else {
-                if (waiterObj.isWaiter()) {
-                    dLockInfo.removeWaiter(waiterObjId);
-                } else {
-                    dLockInfo.removeUpgrader(waiterObjId);
-                }
+            JobInfo jobInfo = jobHT.get(jobId);
+            if (jobInfo == null) {
+                return;
             }
 
-            //2. wake-up waiters
-            latchWaitNotify();
-            synchronized (waiterObj) {
-                unlatchWaitNotify();
-                waiterObj.setWait(false);
+            //remove waiterObj of JobInfo 
+            //[Notice]
+            //waiterObjs may exist if aborted thread is the caller of this function.
+            //Even if there are the waiterObjs, there is no waiting thread on the objects. 
+            //If the caller of this function is an aborted thread, it is guaranteed that there is no waiting threads
+            //on the waiterObjs since when the aborted caller thread is waken up, all other waiting threads are
+            //also waken up at the same time through 'notifyAll()' call.
+            //In contrast, if the caller of this function is not an aborted thread, then there is no waiting object.
+            int waiterObjId = jobInfo.getFirstWaitingResource();
+            int nextWaiterObjId;
+            while (waiterObjId != -1) {
+                existWaiter = true;
+                waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
+                nextWaiterObjId = waiterObj.getNextWaitingResourceObjId();
+                entityInfo = waiterObj.getEntityInfoSlot();
                 if (IS_DEBUG_MODE) {
-                    System.out.println("" + Thread.currentThread().getName() + "\twake-up(D): WID(" + waiterObjId
-                            + "),EID(" + waiterObj.getEntityInfoSlot() + ")");
-                }
-                waiterObj.notifyAll();
-            }
-
-            //3. deallocate waiterObj
-            lockWaiterManager.deallocate(waiterObjId);
-
-            //4. deallocate entityInfo only if this waiter is not an upgrader
-            if (entityInfoManager.getDatasetLockCount(entityInfo) == 0
-                    && entityInfoManager.getEntityLockCount(entityInfo) == 0) {
-                entityInfoManager.deallocate(entityInfo);
-            }
-            waiterObjId = nextWaiterObjId;
-        }
-
-        //release holding resources
-        entityInfo = jobInfo.getLastHoldingResource();
-        while (entityInfo != -1) {
-            prevEntityInfo = entityInfoManager.getPrevJobResource(entityInfo);
-
-            //decrease lock count of datasetLock and entityLock
-            did = entityInfoManager.getDatasetId(entityInfo);
-            tempDatasetIdObj.setId(did);
-            dLockInfo = datasetResourceHT.get(tempDatasetIdObj);
-            entityHashValue = entityInfoManager.getPKHashVal(entityInfo);
-
-            if (entityHashValue == -1) {
-                //decrease datasetLockCount
-                lockMode = entityInfoManager.getDatasetLockMode(entityInfo);
-                datasetLockCount = entityInfoManager.getDatasetLockCount(entityInfo);
-                if (datasetLockCount != 0) {
-                    dLockInfo.decreaseLockCount(lockMode, datasetLockCount);
-
-                    //wakeup waiters of datasetLock and remove holder from datasetLockInfo
-                    wakeUpDatasetLockWaiters(dLockInfo);
-
-                    //remove the holder from datasetLockInfo only if the lock is dataset-granule lock.
-                    //--> this also removes the holding resource from jobInfo               
-                    //(Because the IX and IS lock's holders are handled implicitly, 
-                    //those are not in the holder list of datasetLockInfo.)
-                    dLockInfo.removeHolder(entityInfo, jobInfo);
-                }
-            } else {
-                //decrease datasetLockCount
-                lockMode = entityInfoManager.getDatasetLockMode(entityInfo);
-                lockMode = lockMode == LockMode.S ? LockMode.IS : LockMode.IX;
-                datasetLockCount = entityInfoManager.getDatasetLockCount(entityInfo);
-
-                if (datasetLockCount != 0) {
-                    dLockInfo.decreaseLockCount(lockMode, datasetLockCount);
-                }
-
-                //decrease entityLockCount
-                lockMode = entityInfoManager.getEntityLockMode(entityInfo);
-                entityLockCount = entityInfoManager.getEntityLockCount(entityInfo);
-                eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
-                if (IS_DEBUG_MODE) {
-                    if (eLockInfo < 0) {
-                        System.out.println("eLockInfo:" + eLockInfo);
+                    if (jobId.getId() != entityInfoManager.getJobId(entityInfo)) {
+                        throw new IllegalStateException("JobInfo(" + jobId + ") has diffrent Job(JID:"
+                                + entityInfoManager.getJobId(entityInfo) + "'s lock request!!!");
                     }
                 }
 
-                if (entityLockCount != 0) {
-                    entityLockInfoManager.decreaseLockCount(eLockInfo, lockMode, (short) entityLockCount);
+                //1. remove from waiter(or upgrader)'s list of dLockInfo or eLockInfo.
+                did = entityInfoManager.getDatasetId(entityInfo);
+                tempDatasetIdObj.setId(did);
+                dLockInfo = datasetResourceHT.get(tempDatasetIdObj);
+
+                if (waiterObj.isWaitingOnEntityLock()) {
+                    entityHashValue = entityInfoManager.getPKHashVal(entityInfo);
+                    eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
+                    if (waiterObj.isWaiter()) {
+                        entityLockInfoManager.removeWaiter(eLockInfo, waiterObjId);
+                    } else {
+                        entityLockInfoManager.removeUpgrader(eLockInfo, waiterObjId);
+                    }
+                } else {
+                    if (waiterObj.isWaiter()) {
+                        dLockInfo.removeWaiter(waiterObjId);
+                    } else {
+                        dLockInfo.removeUpgrader(waiterObjId);
+                    }
                 }
 
-                if (datasetLockCount != 0) {
-                    //wakeup waiters of datasetLock and don't remove holder from datasetLockInfo
-                    wakeUpDatasetLockWaiters(dLockInfo);
+                //2. wake-up waiters
+                latchWaitNotify();
+                synchronized (waiterObj) {
+                    unlatchWaitNotify();
+                    waiterObj.setWait(false);
+                    if (IS_DEBUG_MODE) {
+                        System.out.println("" + Thread.currentThread().getName() + "\twake-up(D): WID(" + waiterObjId
+                                + "),EID(" + waiterObj.getEntityInfoSlot() + ")");
+                    }
+                    waiterObj.notifyAll();
                 }
 
-                if (entityLockCount != 0) {
-                    //wakeup waiters of entityLock
-                    wakeUpEntityLockWaiters(eLockInfo);
+                //3. deallocate waiterObj
+                lockWaiterManager.deallocate(waiterObjId);
 
-                    //remove the holder from entityLockInfo 
-                    //--> this also removes the holding resource from jobInfo
-                    entityLockInfoManager.removeHolder(eLockInfo, entityInfo, jobInfo);
+                //4. deallocate entityInfo only if this waiter is not an upgrader
+                if (entityInfoManager.getDatasetLockCount(entityInfo) == 0
+                        && entityInfoManager.getEntityLockCount(entityInfo) == 0) {
+                    entityInfoManager.deallocate(entityInfo);
                 }
-
-                //deallocate entityLockInfo if there is no holder and waiter.
-                if (entityLockInfoManager.getLastHolder(eLockInfo) == -1
-                        && entityLockInfoManager.getFirstWaiter(eLockInfo) == -1
-                        && entityLockInfoManager.getUpgrader(eLockInfo) == -1) {
-                    dLockInfo.getEntityResourceHT().remove(entityHashValue);
-                    entityLockInfoManager.deallocate(eLockInfo);
-                    //                    if (IS_DEBUG_MODE) {
-                    //                        System.out.println("removed PK["+entityHashValue+"]");
-                    //                    }
-                }
+                waiterObjId = nextWaiterObjId;
             }
 
-            //deallocate entityInfo
-            entityInfoManager.deallocate(entityInfo);
-            //            if (IS_DEBUG_MODE) {
-            //                System.out.println("dellocate EntityInfo["+entityInfo+"]");
-            //            }
+            //release holding resources
+            entityInfo = jobInfo.getLastHoldingResource();
+            while (entityInfo != -1) {
+                prevEntityInfo = entityInfoManager.getPrevJobResource(entityInfo);
 
-            entityInfo = prevEntityInfo;
+                //decrease lock count of datasetLock and entityLock
+                did = entityInfoManager.getDatasetId(entityInfo);
+                tempDatasetIdObj.setId(did);
+                dLockInfo = datasetResourceHT.get(tempDatasetIdObj);
+                entityHashValue = entityInfoManager.getPKHashVal(entityInfo);
+
+                if (entityHashValue == -1) {
+                    //decrease datasetLockCount
+                    lockMode = entityInfoManager.getDatasetLockMode(entityInfo);
+                    datasetLockCount = entityInfoManager.getDatasetLockCount(entityInfo);
+                    if (datasetLockCount != 0) {
+                        dLockInfo.decreaseLockCount(lockMode, datasetLockCount);
+
+                        //wakeup waiters of datasetLock and remove holder from datasetLockInfo
+                        wakeUpDatasetLockWaiters(dLockInfo);
+
+                        //remove the holder from datasetLockInfo only if the lock is dataset-granule lock.
+                        //--> this also removes the holding resource from jobInfo               
+                        //(Because the IX and IS lock's holders are handled implicitly, 
+                        //those are not in the holder list of datasetLockInfo.)
+                        dLockInfo.removeHolder(entityInfo, jobInfo);
+                    }
+                } else {
+                    //decrease datasetLockCount
+                    lockMode = entityInfoManager.getDatasetLockMode(entityInfo);
+                    lockMode = lockMode == LockMode.S ? LockMode.IS : LockMode.IX;
+                    datasetLockCount = entityInfoManager.getDatasetLockCount(entityInfo);
+
+                    if (datasetLockCount != 0) {
+                        dLockInfo.decreaseLockCount(lockMode, datasetLockCount);
+                    }
+
+                    //decrease entityLockCount
+                    lockMode = entityInfoManager.getEntityLockMode(entityInfo);
+                    entityLockCount = entityInfoManager.getEntityLockCount(entityInfo);
+                    eLockInfo = dLockInfo.getEntityResourceHT().get(entityHashValue);
+                    if (IS_DEBUG_MODE) {
+                        if (eLockInfo < 0) {
+                            System.out.println("eLockInfo:" + eLockInfo);
+                        }
+                    }
+
+                    if (entityLockCount != 0) {
+                        entityLockInfoManager.decreaseLockCount(eLockInfo, lockMode, (short) entityLockCount);
+                    }
+
+                    if (datasetLockCount != 0) {
+                        //wakeup waiters of datasetLock and don't remove holder from datasetLockInfo
+                        wakeUpDatasetLockWaiters(dLockInfo);
+                    }
+
+                    if (entityLockCount != 0) {
+                        //wakeup waiters of entityLock
+                        wakeUpEntityLockWaiters(eLockInfo);
+
+                        //remove the holder from entityLockInfo 
+                        //--> this also removes the holding resource from jobInfo
+                        entityLockInfoManager.removeHolder(eLockInfo, entityInfo, jobInfo);
+                    }
+
+                    //deallocate entityLockInfo if there is no holder and waiter.
+                    if (entityLockInfoManager.getLastHolder(eLockInfo) == -1
+                            && entityLockInfoManager.getFirstWaiter(eLockInfo) == -1
+                            && entityLockInfoManager.getUpgrader(eLockInfo) == -1) {
+                        dLockInfo.getEntityResourceHT().remove(entityHashValue);
+                        entityLockInfoManager.deallocate(eLockInfo);
+                    }
+                }
+
+                //deallocate entityInfo
+                entityInfoManager.deallocate(entityInfo);
+
+                entityInfo = prevEntityInfo;
+            }
+
+            //remove JobInfo
+            jobHT.remove(jobId);
+
+            if (existWaiter) {
+                txnContext.setStatus(TransactionContext.TIMED_OUT_STATUS);
+                txnContext.setTxnState(TransactionState.ABORTED);
+            }
+
+            if (IS_DEBUG_MODE) {
+                trackLockRequest("Granted", RequestType.RELEASE_LOCKS, new DatasetId(0), 0, (byte) 0, txnContext,
+                        dLockInfo, eLockInfo);
+            }
+        } finally {
+            unlatchLockTable();
         }
-
-        //remove JobInfo
-        jobHT.remove(jobId);
-
-        if (existWaiter) {
-            txnContext.setStatus(TransactionContext.TIMED_OUT_STATUS);
-            txnContext.setTxnState(TransactionState.ABORTED);
-        }
-
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Granted", RequestType.RELEASE_LOCKS, new DatasetId(0), 0, (byte) 0, txnContext,
-                    dLockInfo, eLockInfo);
-        }
-        unlatchLockTable();
     }
 
     @Override
@@ -1008,57 +1007,59 @@
         boolean isSuccess = true;
 
         latchLockTable();
-        validateJob(txnContext);
+        try {
+            validateJob(txnContext);
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Requested", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
-                    txnContext, dLockInfo, -1);
-        }
-
-        dLockInfo = datasetResourceHT.get(datasetId);
-
-        //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
-        if (dLockInfo == null || dLockInfo.isNoHolder()) {
             if (IS_DEBUG_MODE) {
-                trackLockRequest("Granted", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
+                trackLockRequest("Requested", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
                         txnContext, dLockInfo, -1);
             }
 
-            unlatchLockTable();
-            return true;
-        }
+            dLockInfo = datasetResourceHT.get(datasetId);
 
-        //#. the datasetLockInfo exists in datasetResourceHT.
-        //1. handle dataset-granule lock
-        byte datasetLockMode = entityHashValue == -1 ? lockMode : lockMode == LockMode.S ? LockMode.IS : LockMode.IX;
-        if (datasetLockMode == LockMode.IS) {
-            //[Notice]
-            //Skip checking the dataset level lock compatibility if the requested LockMode is IS lock.
-            //We know that this internalInstantTryLock() call with IS lock mode will be always granted 
-            //because we don't allow X lock on dataset-level except DDL operation. 
-            //During DDL operation, all other operations will be pending, so there is no conflict. 
-            isSuccess = true;
-        } else {
-            isSuccess = instantTryLockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext, dLockInfo,
-                    datasetLockMode);
-        }
+            //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
+            if (dLockInfo == null || dLockInfo.isNoHolder()) {
+                if (IS_DEBUG_MODE) {
+                    trackLockRequest("Granted", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
+                            txnContext, dLockInfo, -1);
+                }
+                return true;
+            }
 
-        if (isSuccess && entityHashValue != -1) {
-            //2. handle entity-granule lock
-            isSuccess = instantTryLockEntityGranule(datasetId, entityHashValue, lockMode, txnContext, dLockInfo);
-        }
-
-        if (IS_DEBUG_MODE) {
-            if (isSuccess) {
-                trackLockRequest("Granted", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
-                        txnContext, dLockInfo, -1);
+            //#. the datasetLockInfo exists in datasetResourceHT.
+            //1. handle dataset-granule lock
+            byte datasetLockMode = entityHashValue == -1 ? lockMode : lockMode == LockMode.S ? LockMode.IS
+                    : LockMode.IX;
+            if (datasetLockMode == LockMode.IS) {
+                //[Notice]
+                //Skip checking the dataset level lock compatibility if the requested LockMode is IS lock.
+                //We know that this internalInstantTryLock() call with IS lock mode will be always granted 
+                //because we don't allow X lock on dataset-level except DDL operation. 
+                //During DDL operation, all other operations will be pending, so there is no conflict. 
+                isSuccess = true;
             } else {
-                trackLockRequest("Failed", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
-                        txnContext, dLockInfo, -1);
+                isSuccess = instantTryLockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext, dLockInfo,
+                        datasetLockMode);
             }
-        }
 
-        unlatchLockTable();
+            if (isSuccess && entityHashValue != -1) {
+                //2. handle entity-granule lock
+                isSuccess = instantTryLockEntityGranule(datasetId, entityHashValue, lockMode, txnContext, dLockInfo);
+            }
+
+            if (IS_DEBUG_MODE) {
+                if (isSuccess) {
+                    trackLockRequest("Granted", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
+                            txnContext, dLockInfo, -1);
+                } else {
+                    trackLockRequest("Failed", RequestType.INSTANT_TRY_LOCK, datasetId, entityHashValue, lockMode,
+                            txnContext, dLockInfo, -1);
+                }
+            }
+
+        } finally {
+            unlatchLockTable();
+        }
 
         return isSuccess;
     }
@@ -1217,133 +1218,136 @@
         boolean doEscalate = false;
 
         latchLockTable();
-        validateJob(txnContext);
+        try {
+            validateJob(txnContext);
 
-        if (IS_DEBUG_MODE) {
-            trackLockRequest("Requested", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
-                    dLockInfo, eLockInfo);
-        }
-
-        dLockInfo = datasetResourceHT.get(datasetId);
-        jobInfo = jobHT.get(jobId);
-
-        if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-            if (!isInstant && datasetLockMode == LockMode.IS && jobInfo != null && dLockInfo != null) {
-                int upgradeStatus = needEscalateFromEntityToDataset(jobInfo, dId, lockMode);
-                switch (upgradeStatus) {
-                    case DO_ESCALATE:
-                        entityHashValue = -1;
-                        doEscalate = true;
-                        break;
-
-                    case ESCALATED:
-                        unlatchLockTable();
-                        return true;
-
-                    default:
-                        break;
-                }
-            }
-        }
-
-        //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
-        if (dLockInfo == null || dLockInfo.isNoHolder()) {
-            if (dLockInfo == null) {
-                dLockInfo = new DatasetLockInfo(entityLockInfoManager, entityInfoManager, lockWaiterManager);
-                datasetResourceHT.put(new DatasetId(dId), dLockInfo); //datsetId obj should be created
-            }
-            entityInfo = entityInfoManager.allocate(jId, dId, entityHashValue, lockMode);
-
-            //if dataset-granule lock
-            if (entityHashValue == -1) { //-1 stands for dataset-granule
-                entityInfoManager.increaseDatasetLockCount(entityInfo);
-                dLockInfo.increaseLockCount(datasetLockMode);
-                dLockInfo.addHolder(entityInfo);
-            } else {
-                entityInfoManager.increaseDatasetLockCount(entityInfo);
-                dLockInfo.increaseLockCount(datasetLockMode);
-                //add entityLockInfo
-                eLockInfo = entityLockInfoManager.allocate();
-                dLockInfo.getEntityResourceHT().put(entityHashValue, eLockInfo);
-                entityInfoManager.increaseEntityLockCount(entityInfo);
-                entityLockInfoManager.increaseLockCount(eLockInfo, lockMode);
-                entityLockInfoManager.addHolder(eLockInfo, entityInfo);
+            if (IS_DEBUG_MODE) {
+                trackLockRequest("Requested", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                        dLockInfo, eLockInfo);
             }
 
-            if (jobInfo == null) {
-                jobInfo = new JobInfo(entityInfoManager, lockWaiterManager, txnContext);
-                jobHT.put(jobId, jobInfo); //jobId obj doesn't have to be created
-            }
-            jobInfo.addHoldingResource(entityInfo);
+            dLockInfo = datasetResourceHT.get(datasetId);
+            jobInfo = jobHT.get(jobId);
 
             if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-                if (!isInstant && datasetLockMode == LockMode.IS) {
-                    jobInfo.increaseDatasetISLockCount(dId);
+                if (!isInstant && datasetLockMode == LockMode.IS && jobInfo != null && dLockInfo != null) {
+                    int upgradeStatus = needEscalateFromEntityToDataset(jobInfo, dId, lockMode);
+                    switch (upgradeStatus) {
+                        case DO_ESCALATE:
+                            entityHashValue = -1;
+                            doEscalate = true;
+                            break;
+
+                        case ESCALATED:
+                            return true;
+
+                        default:
+                            break;
+                    }
+                }
+            }
+
+            //#. if the datasetLockInfo doesn't exist in datasetResourceHT 
+            if (dLockInfo == null || dLockInfo.isNoHolder()) {
+                if (dLockInfo == null) {
+                    dLockInfo = new DatasetLockInfo(entityLockInfoManager, entityInfoManager, lockWaiterManager);
+                    datasetResourceHT.put(new DatasetId(dId), dLockInfo); //datsetId obj should be created
+                }
+                entityInfo = entityInfoManager.allocate(jId, dId, entityHashValue, lockMode);
+
+                //if dataset-granule lock
+                if (entityHashValue == -1) { //-1 stands for dataset-granule
+                    entityInfoManager.increaseDatasetLockCount(entityInfo);
+                    dLockInfo.increaseLockCount(datasetLockMode);
+                    dLockInfo.addHolder(entityInfo);
+                } else {
+                    entityInfoManager.increaseDatasetLockCount(entityInfo);
+                    dLockInfo.increaseLockCount(datasetLockMode);
+                    //add entityLockInfo
+                    eLockInfo = entityLockInfoManager.allocate();
+                    dLockInfo.getEntityResourceHT().put(entityHashValue, eLockInfo);
+                    entityInfoManager.increaseEntityLockCount(entityInfo);
+                    entityLockInfoManager.increaseLockCount(eLockInfo, lockMode);
+                    entityLockInfoManager.addHolder(eLockInfo, entityInfo);
+                }
+
+                if (jobInfo == null) {
+                    jobInfo = new JobInfo(entityInfoManager, lockWaiterManager, txnContext);
+                    jobHT.put(jobId, jobInfo); //jobId obj doesn't have to be created
+                }
+                jobInfo.addHoldingResource(entityInfo);
+
+                if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
+                    if (!isInstant && datasetLockMode == LockMode.IS) {
+                        jobInfo.increaseDatasetISLockCount(dId);
+                        if (doEscalate) {
+                            //This exception is thrown when the threshold value is set to 1.
+                            //We don't want to allow the lock escalation when there is a first lock request on a dataset. 
+                            throw new IllegalStateException(
+                                    "ESCALATE_TRHESHOLD_ENTITY_TO_DATASET should not be set to "
+                                            + ESCALATE_TRHESHOLD_ENTITY_TO_DATASET);
+                        }
+                    }
+                }
+
+                if (IS_DEBUG_MODE) {
+                    trackLockRequest("Granted", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                            dLockInfo, eLockInfo);
+                }
+
+                return true;
+            }
+
+            //#. the datasetLockInfo exists in datasetResourceHT.
+            //1. handle dataset-granule lock
+            tryLockDatasetGranuleRevertOperation = 0;
+            entityInfo = tryLockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext);
+            if (entityInfo == -2) {//-2 represents fail
+                isSuccess = false;
+            } else {
+                //2. handle entity-granule lock
+                if (entityHashValue != -1) {
+                    isSuccess = tryLockEntityGranule(datasetId, entityHashValue, lockMode, entityInfo, txnContext);
+                    if (!isSuccess) {
+                        revertTryLockDatasetGranuleOperation(datasetId, entityHashValue, lockMode, entityInfo,
+                                txnContext);
+                    }
+                }
+            }
+
+            if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
+                if (!isInstant) {
                     if (doEscalate) {
-                        //This exception is thrown when the threshold value is set to 1.
-                        //We don't want to allow the lock escalation when there is a first lock request on a dataset. 
-                        throw new IllegalStateException("ESCALATE_TRHESHOLD_ENTITY_TO_DATASET should not be set to "
-                                + ESCALATE_TRHESHOLD_ENTITY_TO_DATASET);
+                        //jobInfo must not be null.
+                        assert jobInfo != null;
+                        jobInfo.increaseDatasetISLockCount(dId);
+                        //release pre-acquired locks
+                        releaseDatasetISLocks(jobInfo, jobId, datasetId, txnContext);
+                    } else if (datasetLockMode == LockMode.IS) {
+                        if (jobInfo == null) {
+                            jobInfo = jobHT.get(jobId);
+                            //jobInfo must not be null;
+                            assert jobInfo != null;
+                        }
+                        jobInfo.increaseDatasetISLockCount(dId);
                     }
                 }
             }
 
             if (IS_DEBUG_MODE) {
-                trackLockRequest("Granted", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
-                        dLockInfo, eLockInfo);
+                if (isSuccess) {
+                    trackLockRequest("Granted", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                            dLockInfo, eLockInfo);
+                } else {
+                    trackLockRequest("Failed", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
+                            dLockInfo, eLockInfo);
+                }
             }
 
+        } finally {
             unlatchLockTable();
-            return true;
         }
 
-        //#. the datasetLockInfo exists in datasetResourceHT.
-        //1. handle dataset-granule lock
-        tryLockDatasetGranuleRevertOperation = 0;
-        entityInfo = tryLockDatasetGranule(datasetId, entityHashValue, lockMode, txnContext);
-        if (entityInfo == -2) {//-2 represents fail
-            isSuccess = false;
-        } else {
-            //2. handle entity-granule lock
-            if (entityHashValue != -1) {
-                isSuccess = tryLockEntityGranule(datasetId, entityHashValue, lockMode, entityInfo, txnContext);
-                if (!isSuccess) {
-                    revertTryLockDatasetGranuleOperation(datasetId, entityHashValue, lockMode, entityInfo, txnContext);
-                }
-            }
-        }
-
-        if (ALLOW_ESCALATE_FROM_ENTITY_TO_DATASET) {
-            if (!isInstant) {
-                if (doEscalate) {
-                    //jobInfo must not be null.
-                    assert jobInfo != null;
-                    jobInfo.increaseDatasetISLockCount(dId);
-                    //release pre-acquired locks
-                    releaseDatasetISLocks(jobInfo, jobId, datasetId, txnContext);
-                } else if (datasetLockMode == LockMode.IS) {
-                    if (jobInfo == null) {
-                        jobInfo = jobHT.get(jobId);
-                        //jobInfo must not be null;
-                        assert jobInfo != null;
-                    }
-                    jobInfo.increaseDatasetISLockCount(dId);
-                }
-            }
-        }
-
-        if (IS_DEBUG_MODE) {
-            if (isSuccess) {
-                trackLockRequest("Granted", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
-                        dLockInfo, eLockInfo);
-            } else {
-                trackLockRequest("Failed", RequestType.TRY_LOCK, datasetId, entityHashValue, lockMode, txnContext,
-                        dLockInfo, eLockInfo);
-            }
-        }
-
-        unlatchLockTable();
-
         return isSuccess;
     }
 
@@ -1778,38 +1782,38 @@
 
             latchWaitNotify();
             unlatchLockTable();
-            synchronized (waiter) {
-                unlatchWaitNotify();
-                while (waiter.needWait()) {
-                    try {
-                        if (IS_DEBUG_MODE) {
-                            System.out.println("" + Thread.currentThread().getName() + "\twaits("
-                                    + waiter.getWaiterCount() + "): WID(" + waiterId + "),EID("
-                                    + waiter.getEntityInfoSlot() + ")");
+            try {
+                synchronized (waiter) {
+                    unlatchWaitNotify();
+                    while (waiter.needWait()) {
+                        try {
+                            if (IS_DEBUG_MODE) {
+                                System.out.println("" + Thread.currentThread().getName() + "\twaits("
+                                        + waiter.getWaiterCount() + "): WID(" + waiterId + "),EID("
+                                        + waiter.getEntityInfoSlot() + ")");
+                            }
+                            waiter.wait();
+                        } catch (InterruptedException e) {
+                            //TODO figure-out what is the appropriate way to handle this exception
+                            e.printStackTrace();
+                            isInterruptedExceptionOccurred = true;
+                            waiter.setWait(false);
                         }
-                        waiter.wait();
-                    } catch (InterruptedException e) {
-                        //TODO figure-out what is the appropriate way to handle this exception
-                        e.printStackTrace();
-                        isInterruptedExceptionOccurred = true;
-                        waiter.setWait(false);
                     }
                 }
-            }
 
-            if (isInterruptedExceptionOccurred) {
-                throw new ACIDException("InterruptedException is caught");
+                if (isInterruptedExceptionOccurred) {
+                    throw new ACIDException("InterruptedException is caught");
+                }
+            } catch (Exception e) {
+                throw new LockMgrLatchHandlerException(e);
             }
 
             //waiter woke up -> remove/deallocate waiter object and abort if timeout
             latchLockTable();
 
             if (txnContext.getStatus() == TransactionContext.TIMED_OUT_STATUS || waiter.isVictim()) {
-                try {
-                    requestAbort(txnContext);
-                } finally {
-                    unlatchLockTable();
-                }
+                requestAbort(txnContext);
             }
 
             if (waiter.isFirstGetUp()) {
@@ -1853,11 +1857,7 @@
                 //deallocate the entityInfo
                 entityInfoManager.deallocate(entityInfo);
             }
-            try {
-                requestAbort(txnContext);
-            } finally {
-                unlatchLockTable();
-            }
+            requestAbort(txnContext);
         }
 
         return waiterCount;
@@ -2028,20 +2028,22 @@
         LockWaiter waiterObj;
 
         latchLockTable();
+        try {
 
-        Iterator<Entry<JobId, JobInfo>> iter = jobHT.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry<JobId, JobInfo> pair = (Map.Entry<JobId, JobInfo>) iter.next();
-            jobInfo = pair.getValue();
-            waiterObjId = jobInfo.getFirstWaitingResource();
-            while (waiterObjId != -1) {
-                waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
-                toutDetector.checkAndSetVictim(waiterObj);
-                waiterObjId = waiterObj.getNextWaiterObjId();
+            Iterator<Entry<JobId, JobInfo>> iter = jobHT.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<JobId, JobInfo> pair = (Map.Entry<JobId, JobInfo>) iter.next();
+                jobInfo = pair.getValue();
+                waiterObjId = jobInfo.getFirstWaitingResource();
+                while (waiterObjId != -1) {
+                    waiterObj = lockWaiterManager.getLockWaiter(waiterObjId);
+                    toutDetector.checkAndSetVictim(waiterObj);
+                    waiterObjId = waiterObj.getNextWaiterObjId();
+                }
             }
+        } finally {
+            unlatchLockTable();
         }
-
-        unlatchLockTable();
     }
 }
 
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockMgrLatchHandlerException.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockMgrLatchHandlerException.java
new file mode 100644
index 0000000..05a582c
--- /dev/null
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/LockMgrLatchHandlerException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012-2014 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.transaction.management.service.locking;
+
+import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
+
+public class LockMgrLatchHandlerException extends ACIDException {
+
+    private static final long serialVersionUID = 1203182080428864199L;
+    private final Exception internalException;
+
+    public LockMgrLatchHandlerException(Exception e) {
+        super(e);
+        this.internalException = e;
+    }
+
+    public Exception getInternalException() {
+        return internalException;
+    }
+}
\ No newline at end of file