private void produceEntityLockRequest(byte lockMode) throws ACIDException {
   int requestType = rand.nextInt(MAX_LOCK_REQUEST_TYPE_NUM);
   int datasetId = rand.nextInt(MAX_DATASET_NUM);
   int entityHashValue = rand.nextInt(MAX_ENTITY_NUM);
   LockRequest request =
       new LockRequest(
           Thread.currentThread().getName(),
           requestType,
           new DatasetId(datasetId),
           entityHashValue,
           lockMode,
           txnContext);
   requestQueue.add(request);
   requestHistory.append(request.prettyPrint());
   sendRequest(request);
 }
  private void produceDatasetUnlockRequest() throws ACIDException {
    LockRequest lockRequest = requestQueue.get(0);

    int requestType = RequestType.RELEASE_LOCKS;
    int datasetId = lockRequest.datasetIdObj.getId();
    int entityHashValue = -1;
    byte lockMode = LockMode.S; // lockMode is not used for unlock() call.
    LockRequest request =
        new LockRequest(
            Thread.currentThread().getName(),
            requestType,
            new DatasetId(datasetId),
            entityHashValue,
            lockMode,
            txnContext);
    requestQueue.add(request);
    requestHistory.append(request.prettyPrint());
    sendRequest(request);
  }
  private void produceEntityLockUpgradeRequest() throws ACIDException {
    LockRequest lockRequest = null;
    int size = requestQueue.size();
    boolean existLockRequest = false;

    while (upgradeIndex < size) {
      lockRequest = requestQueue.get(upgradeIndex++);
      if (lockRequest.isUpgrade || lockRequest.isTryLockFailed) {
        continue;
      }
      if (lockRequest.requestType == RequestType.UNLOCK
          || lockRequest.requestType == RequestType.RELEASE_LOCKS
          || lockRequest.requestType == RequestType.INSTANT_LOCK
          || lockRequest.requestType == RequestType.INSTANT_TRY_LOCK) {
        continue;
      }
      if (lockRequest.lockMode == LockMode.X) {
        continue;
      }
      existLockRequest = true;
      break;
    }

    if (existLockRequest) {
      int requestType = lockRequest.requestType;
      int datasetId = lockRequest.datasetIdObj.getId();
      int entityHashValue = lockRequest.entityHashValue;
      byte lockMode = LockMode.X;
      LockRequest request =
          new LockRequest(
              Thread.currentThread().getName(),
              requestType,
              new DatasetId(datasetId),
              entityHashValue,
              lockMode,
              txnContext);
      request.isUpgrade = true;
      requestQueue.add(request);
      requestHistory.append(request.prettyPrint());
      sendRequest(request);
    }
  }
  private void sendRequest(LockRequest request) throws ACIDException {

    switch (request.requestType) {
      case RequestType.LOCK:
        try {
          lockMgr.lock(
              request.datasetIdObj, request.entityHashValue, request.lockMode, request.txnContext);
        } catch (ACIDException e) {
          if (request.txnContext.isTimeout()) {
            if (request.txnContext.getTxnState() != ITransactionManager.ABORTED) {
              request.txnContext.setTxnState(ITransactionManager.ABORTED);
              log("*** " + request.txnContext.getJobId() + " lock request causing deadlock ***");
              log("Abort --> Releasing all locks acquired by " + request.txnContext.getJobId());
              try {
                lockMgr.releaseLocks(request.txnContext);
              } catch (ACIDException e1) {
                e1.printStackTrace();
              }
              log("Abort --> Released all locks acquired by " + request.txnContext.getJobId());
            }
            isDone = true;
          } else {
            throw e;
          }
        }
        break;
      case RequestType.INSTANT_LOCK:
        try {
          lockMgr.instantLock(
              request.datasetIdObj, request.entityHashValue, request.lockMode, request.txnContext);
        } catch (ACIDException e) {
          if (request.txnContext.isTimeout()) {
            if (request.txnContext.getTxnState() != ITransactionManager.ABORTED) {
              request.txnContext.setTxnState(ITransactionManager.ABORTED);
              log("*** " + request.txnContext.getJobId() + " lock request causing deadlock ***");
              log("Abort --> Releasing all locks acquired by " + request.txnContext.getJobId());
              try {
                lockMgr.releaseLocks(request.txnContext);
              } catch (ACIDException e1) {
                e1.printStackTrace();
              }
              log("Abort --> Released all locks acquired by " + request.txnContext.getJobId());
            }
            isDone = true;
          } else {
            throw e;
          }
        }
        break;
      case RequestType.TRY_LOCK:
        request.isTryLockFailed =
            !lockMgr.tryLock(
                request.datasetIdObj,
                request.entityHashValue,
                request.lockMode,
                request.txnContext);
        break;
      case RequestType.INSTANT_TRY_LOCK:
        lockMgr.instantTryLock(
            request.datasetIdObj, request.entityHashValue, request.lockMode, request.txnContext);
        break;
      case RequestType.UNLOCK:
        lockMgr.unlock(
            request.datasetIdObj, request.entityHashValue, request.lockMode, request.txnContext);
        break;
      case RequestType.RELEASE_LOCKS:
        lockMgr.releaseLocks(request.txnContext);
        break;
      default:
        throw new UnsupportedOperationException("Unsupported lock method");
    }
    try {
      Thread.sleep((long) 0);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }