예제 #1
0
 // This is thread-safe and cannot deadlock; takes the locks in the
 // order determined by the Account object's serial number.
 public void transferD(Account that, final long amount) {
   Account ac1 = this, ac2 = that;
   if (ac1.serial <= ac2.serial)
     synchronized (ac1) {
       synchronized (ac2) { // ac1 < ac2
         ac1.balance = ac1.balance - amount;
         ac2.balance = ac2.balance + amount;
       }
     }
   else
     synchronized (ac2) {
       synchronized (ac1) { // ac2 < ac1
         ac1.balance = ac1.balance - amount;
         ac2.balance = ac2.balance + amount;
       }
     }
 }
예제 #2
0
 private void createAccounts()
     throws IOException, DeadlockException, InterruptedException, TransactionRolledBackException {
   for (int a = 0; a < nAccounts; a++) {
     Account account = new Account(new AccountId(a));
     account.balance(0);
     accounts.ensurePresent(account);
   }
   db.commitTransaction();
 }
예제 #3
0
  // This is thread-safe but may deadlock; takes the locks in the
  // order determined by the Account object's hashCode.  May deadlock
  // in (the rare) case distinct objects get identical hashcodes; this
  // case may be handled using a third lock, as in Goetz p. 209.
  public void transferE(Account that, final long amount) {
    Account ac1 = this, ac2 = that;
    int ac1Hash = System.identityHashCode(ac1);
    int ac2Hash = System.identityHashCode(ac2);

    if (ac1Hash < ac2Hash)
      synchronized (ac1) {
        synchronized (ac2) { // ac1 < ac2
          ac1.balance = ac1.balance - amount;
          ac2.balance = ac2.balance + amount;
        }
      }
    else if (ac1Hash > ac2Hash)
      synchronized (ac2) {
        synchronized (ac1) { // ac2 < ac1
          ac1.balance = ac1.balance - amount;
          ac2.balance = ac2.balance + amount;
        }
      }
    else
      synchronized (tieLock) {
        synchronized (ac1) {
          synchronized (ac2) { // ac1 < ac2
            ac1.balance = ac1.balance - amount;
            ac2.balance = ac2.balance + amount;
          }
        }
      }
  }
예제 #4
0
 private void verify() throws IOException, InterruptedException {
   long sum = 0;
   Cursor cursor = accounts.first();
   Account account;
   while ((account = (Account) cursor.next()) != null) {
     LOG.log(Level.INFO, "{0}", account);
     sum += account.balance();
   }
   db.commitTransaction();
   if (sum == 0) {
     LOG.log(Level.INFO, "OK!");
   } else {
     LOG.log(Level.WARNING, "Test failed, sum = {0}", sum);
   }
 }
  public static void main(String[] args) {
    Account mike;
    mike = new Account(1000);
    System.out.println(mike.balance());
    mike.deposit(100);
    System.out.println(mike.balance());
    mike.withdraw(200);
    System.out.println(mike.balance());

    // overdraft test
    Account Tom;
    Tom = new Account(2000);
    Account Kate;
    Kate = new Account(1000, Tom);
    Kate.withdraw(1001);
    if (Kate.balance() == 0 && Tom.balance() == 1999) {
    } else {

      System.out.println("Error: Overdraft test failed");
    }

    // withdraw boolean tests
    Account peter = new Account(90);

    boolean bool1 = peter.withdraw(-5);
    boolean bool2 = peter.withdraw(100);
    boolean bool3 = peter.withdraw(50);

    if (!bool1 && !bool2 && bool3) {
    } else {
      System.out.println("Error: Withdraw failed");
    }

    // merge tests
    Account tyler = new Account(500);
    Account bob = new Account(900);

    tyler.merge(bob);

    if (tyler.balance() == 1400 && bob.balance() == 0) {
    } else {
      System.out.println("Error: Merge test failed");
    }
  } // end main
예제 #6
0
 public void run() {
   int deadlockAborts = 0;
   int conflictAborts = 0;
   try {
     for (int i = 0; i < nTransactions; i++) {
       boolean committed = false;
       StringBuilder description = new StringBuilder();
       do {
         transaction = transaction();
         int from;
         int to;
         do {
           from = random.nextInt(nAccounts);
           to = random.nextInt(nAccounts);
         } while (from == to);
         int amount = MIN_AMOUNT + random.nextInt(MAX_AMOUNT);
         AccountId fromAccountId = new AccountId(from);
         AccountId toAccountId = new AccountId(to);
         try {
           Account fromAccount = account(fromAccountId);
           Account toAccount = account(toAccountId);
           if (LOG.isLoggable(Level.INFO)) {
             LOG.log(
                 Level.INFO,
                 "{0}: Attempt transfer of {1} from {2} to {3}",
                 new Object[] {transaction, amount, fromAccountId, toAccountId});
           }
           description.setLength(0);
           description.append(String.format("%s, %s", fromAccount, toAccount));
           fromAccount.balance(fromAccount.balance() - amount);
           toAccount.balance(toAccount.balance() + amount);
           description.append(String.format(" -> %s, %s", fromAccount, toAccount));
           accounts.ensurePresent(fromAccount);
           accounts.ensurePresent(toAccount);
           db.commitTransaction(transactionCallback);
           committed = true;
           if (LOG.isLoggable(Level.INFO)) {
             LOG.log(
                 Level.INFO,
                 "{0}: Transferred {1}: {2}",
                 new Object[] {transaction, amount, description});
           }
         } catch (com.geophile.erdo.transaction.DeadlockException e) {
           LOG.log(
               Level.INFO,
               "{0}: transfer of {1} from {2} to {3} failed due to deadlock",
               new Object[] {transaction, amount, fromAccountId, toAccountId});
           deadlockAborts++;
         } catch (TransactionRolledBackException e) {
           LOG.log(
               Level.INFO,
               "{0}: transfer of {1} from {2} to {3} failed due to conflict",
               new Object[] {transaction, amount, fromAccountId, toAccountId});
           conflictAborts++;
         }
       } while (!committed);
     }
   } catch (Throwable th) {
     LOG.log(Level.SEVERE, "Caught exception", th);
     termination = th;
   } finally {
     LOG.log(
         Level.INFO,
         "{0} transactions, {1} deadlock aborts, {2} conflict aborts, termination: {3}",
         new Object[] {
           nTransactions,
           deadlockAborts,
           conflictAborts,
           (termination == null ? null : termination.getMessage())
         });
   }
 }
예제 #7
0
 public Account createAccount(BigDecimal balance) {
   Account account = new Account();
   account.balance = balance;
   account.name = generateString(new Random(), "Test name", 10);
   return account;
 }