// Returns price of cars at this location public ReturnTuple<Integer> queryCarsPrice(int id, String location, Timestamp timestamp) throws RemoteException, TransactionAbortedException, InvalidTransactionException { if (!isMaster) { System.out.println("Slave retransmitting queryCarsPrice to master"); return this.getMaster().queryCarsPrice(id, location, timestamp); } else { QueryCarsPriceRMICommand qcp = new QueryCarsPriceRMICommand(roomGroup, id, location); qcp.setTimestampObject(timestamp); ReturnTuple<Integer> result = null; try { overseer.validTransaction(id); lm.Lock(id, Car.getKey(location), qcp.getRequiredLock()); qcp.execute(); result = qcp.price; } catch (DeadlockException d) { timestamp.stamp(); overseer.abort(id); timestamp.stamp(); throw new TransactionAbortedException(timestamp); } catch (TransactionAbortedException tae) { tae.t = timestamp; throw tae; } catch (InvalidTransactionException ite) { ite.t = timestamp; throw ite; } result.timestamp.stamp(); return result; } }
// Delete cars from a location public ReturnTuple<Boolean> deleteCars(int id, String location, Timestamp timestamp) throws RemoteException, TransactionAbortedException, InvalidTransactionException { if (!isMaster) { System.out.println("Slave retransmitting deleteCars to master"); return this.getMaster().deleteCars(id, location, timestamp); } else { timestamp.stamp(); DeleteCarsRMICommand dc = new DeleteCarsRMICommand(carGroup, id, location); dc.setTimestampObject(timestamp); ReturnTuple<Boolean> result = null; try { overseer.validTransaction(id); lm.Lock(id, Car.getKey(location), dc.getRequiredLock()); dc.execute(); result = dc.success; if (result.result) overseer.addCommandToTransaction(id, dc); } catch (DeadlockException d) { timestamp.stamp(); overseer.abort(id); timestamp.stamp(); throw new TransactionAbortedException(timestamp); } catch (TransactionAbortedException tae) { tae.t = timestamp; throw tae; } catch (InvalidTransactionException ite) { ite.t = timestamp; throw ite; } result.timestamp.stamp(); return result; } }
// Create a new car location or add cars to an existing location. // Note: if price <= 0 and the car location already exists, it maintains // its current price. @Override public boolean addCars(int id, String location, int numCars, int carPrice) { Trace.info( "RM::addCars(" + id + ", " + location + ", " + numCars + ", $" + carPrice + ") called."); synchronized (syncLock) { Car curObj = (Car) readData(id, Car.getKey(location)); if (curObj == null) { // Doesn't exist; add it. Car newObj = new Car(location, numCars, carPrice); writeData(id, newObj.getKey(), newObj); Trace.info( "RM::addCars(" + id + ", " + location + ", " + numCars + ", $" + carPrice + ") OK."); } else { // Add count to existing object and update price. curObj.setCount(curObj.getCount() + numCars); if (carPrice > 0) { curObj.setPrice(carPrice); } writeData(id, curObj.getKey(), curObj); Trace.info( "RM::addCars(" + id + ", " + location + ", " + numCars + ", $" + carPrice + ") OK: " + "cars = " + curObj.getCount() + ", price = $" + carPrice); } return (true); } }
// return a bill public ReturnTuple<String> queryCustomerInfo(int id, int customerID, Timestamp timestamp) throws RemoteException, TransactionAbortedException, InvalidTransactionException { if (!isMaster) { System.out.println("Slave retransmitting queryCustomerInfo to master"); return this.getMaster().queryCustomerInfo(id, customerID, timestamp); } else { timestamp.stamp(); QueryCustomerInfoRMICommand qci = new QueryCustomerInfoRMICommand(carGroup, flightGroup, roomGroup, id, customerID); qci.setTimestampObject(timestamp); ReturnTuple<String> result = null; try { Vector<Integer> flightNos; Vector<String> locations; overseer.validTransaction(id); lm.Lock(id, Customer.getKey(customerID), qci.getRequiredLock()); qci.execute(); flightNos = qci.getCustomerFlightReservations(); for (int flightNo : flightNos) { lm.Lock(id, Flight.getKey(flightNo), qci.getRequiredLock()); } locations = qci.getCustomerRoomReservations(); for (String location : locations) { lm.Lock(id, Hotel.getKey(location), qci.getRequiredLock()); } locations = qci.getCustomerCarReservations(); for (String location : locations) { lm.Lock(id, Car.getKey(location), qci.getRequiredLock()); } qci.execute(); result = qci.customerInfo; } catch (DeadlockException d) { timestamp.stamp(); overseer.abort(id); timestamp.stamp(); throw new TransactionAbortedException(timestamp); } catch (TransactionAbortedException tae) { tae.t = timestamp; throw tae; } catch (InvalidTransactionException ite) { ite.t = timestamp; throw ite; } result.timestamp.stamp(); return result; } }
// Add car reservation to this customer. @Override public boolean cancelReserveCar(int id, int customerId, String location) { return cancelReserveItem(id, customerId, Car.getKey(location), location); }
// Returns price of cars at this location. @Override public int queryCarsPrice(int id, String location) { return queryPrice(id, Car.getKey(location)); }
// Delete cars from a location. @Override public boolean deleteCars(int id, String location) { return deleteItem(id, Car.getKey(location)); }
// Adds car reservation to this customer. public boolean reserveCar(int id, int customerID, String location) throws RemoteException { return reserveItem(id, customerID, Car.getKey(location), location); }
// Returns price of cars at this location public int queryCarsPrice(int id, String location) throws RemoteException { return queryPrice(id, Car.getKey(location)); }
// Delete cars from a location public boolean deleteCars(int id, String location) throws RemoteException { return deleteItem(id, Car.getKey(location)); }