/** * performs the read operation for both Read-Write and Read-Only Transactions * * @param transactionID * @param variable * @param typeOfTransaction */ private void read(String transactionID, int variable, int typeOfTransaction) { Transaction transactionForReading = this.currentTransactions.get(transactionID); if (typeOfTransaction == Constants.RO) { // for read only transaction boolean hasItBeenRead = false; for (int i = 1; i <= Constants.SITES && !hasItBeenRead; i++) { Site tempSite = sites.get(i); if (tempSite.isDown()) { // site is down // Do not do anything, go to next site } else { // site is not down ArrayList<Variable> variablesInTempSite = (ArrayList<Variable>) tempSite.getVariables(); for (int j = 0; j < variablesInTempSite.size(); j++) { if (variablesInTempSite.get(j).getID() == variable && variablesInTempSite.get(j).getAvailableForRead()) { // variable we are looking for found in tempSite and they are available for reading // We have parse the VariableHistory of this Variable and choose the correct value ArrayList<VariableHistory> history = (ArrayList<VariableHistory>) variablesInTempSite.get(j).getHistoricalData(); int currentMax = -1; // time counter int maxIndex = -1; // index in the ArrayList which has max for (int k = 0; k < history.size(); k++) { if (history.get(k).getTime() > currentMax && history.get(k).getTime() < transactionForReading.getStartTime()) { maxIndex = k; currentMax = history.get(k).getTime(); } } if (maxIndex != -1) { hasItBeenRead = true; System.out.println("The value that is read is " + history.get(maxIndex).getValue()); Operation op = new Operation(0, variable, 0, Constants.OP_READ); transactionForReading.insertOperation(op); } } } } } if (hasItBeenRead == false) { // variable could not be read for any site so this operation has to wait System.out.println(transactionID + "(R,x" + variable + ") has to wait"); Operation op = new Operation(0, variable, 0, Constants.OP_READ); insertToWaitList(op, transactionID); } } else { // for read-write transaction if (this.doesThisTransactionAlreadyHaveReadLockOnVariable(transactionForReading, variable)) { // transaction already has a read lock on variable at some site int index = -1; for (int q = 1; q <= Constants.SITES; q++) { if (!this.sites.get(q).isDown()) { if (this.sites .get(q) .lockInfo .doesThisTableContainLockWith(variable, transactionID, Constants.RL)) { index = q; } } } ArrayList<Variable> varsInSite = (ArrayList<Variable>) this.sites.get(index).getVariables(); Variable var = varsInSite.get(0); for (int m = 0; m < varsInSite.size(); m++) { if (varsInSite.get(m).getID() == variable) { var = varsInSite.get(m); } } System.out.println("The value that is read is " + var.getValue()); } else { // the transaction does not have a read lock on this variable boolean hasItBeenRead = false; for (int i = 1; i <= Constants.SITES && !hasItBeenRead; i++) { Site tempSite = sites.get(i); if (tempSite.isDown()) { // site is down // Do not do anything } else { // site is not down ArrayList<Variable> variablesInTempSite = (ArrayList<Variable>) tempSite.getVariables(); for (int j = 0; j < variablesInTempSite.size(); j++) { if (variablesInTempSite.get(j).getID() == variable && variablesInTempSite.get(j).getAvailableForRead()) { // variable we are looking for found in tempSite and they are available for // reading(in term of recovery) if (tempSite.lockInfo.canWeGetReadLockOnVariable(variable, transactionID)) { // we can get read lock on the variable if (tempSite.lockInfo.doesThisTableContainLockWith( variable, transactionID, Constants.WL)) { // this transaction has a write lock on the this variable at this site hasItBeenRead = true; Variable currentVariable = tempSite.getVariableWithID(variable); Operation op = new Operation(0, variable, 0, Constants.OP_READ); transactionForReading.insertOperation(op); transactionForReading.sitesAccessed.add(i); System.out.println( "The value that is read is " + currentVariable.getCurrValue()); // value read is the current value because transaction already has read lock on // the variable } else { // this transaction does not have a write lock on this variable hasItBeenRead = true; tempSite.lockInfo.addLock(variable, transactionID, Constants.RL); Variable currentVariable = tempSite.getVariableWithID(variable); Operation op = new Operation(0, variable, 0, Constants.OP_READ); transactionForReading.insertOperation(op); transactionForReading.sitesAccessed.add(i); transactionForReading.addLockToAlreadyLocked(variable, Constants.RL); System.out.println("The value that is read is " + currentVariable.getValue()); } } else { // this is the variable that we want to lock // but we can't get a read lock on it // so implement wait-die hasItBeenRead = true; ArrayList<Lock> tempList = tempSite.lockInfo.getAllLocksForVariable(variable); Lock writeLock = tempList.get(0); String tidWithWriteLock = writeLock.getTransactionId(); String tidWithoutWriteLock = transactionID; boolean answer = isAbort(tidWithWriteLock, tidWithoutWriteLock); if (answer == false) { // This operation has to wait this.putThisTransactionIntoWaitListingOfTransactionThatHaveLock( transactionID, variable); Operation op = new Operation(0, variable, 0, Constants.OP_READ); insertToWaitList(op, transactionID); System.out.println(transactionID + "(R,x" + variable + ") has to wait"); } } } } } } if (hasItBeenRead == false) { // variable could not be read for any site so this operation has to wait Operation op = new Operation(0, variable, 0, Constants.OP_READ); insertToWaitList(op, transactionID); System.out.println(transactionID + "(R,x" + variable + ") has to wait"); } } } }