Search in sources :

Example 1 with Account

use of org.datanucleus.samples.concurrency.Account in project tests by datanucleus.

the class ConcurrencyTest method testBasicConcurrency.

public void testBasicConcurrency() {
    // Persist Accounts and Transfers
    PersistenceManager pm = pmf.getPersistenceManager();
    pm.setProperty(PropertyNames.PROPERTY_SERIALIZE_READ, "true");
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        pm.makePersistent(new Account("alice", 1000));
        pm.makePersistent(new Account("berta", 0));
        pm.makePersistent(new Account("charly", 0));
        pm.makePersistent(new Transfer("alice", "berta", 100));
        pm.makePersistent(new Transfer("alice", "charly", 200));
        tx.commit();
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
    // Process the Transfers, one per Thread, and one PM per Thread
    pm = pmf.getPersistenceManager();
    pm.setProperty(PropertyNames.PROPERTY_SERIALIZE_READ, "true");
    tx = pm.currentTransaction();
    try {
        tx.begin();
        LinkedList<Thread> threads = new LinkedList<>();
        Extent ext = pm.getExtent(Transfer.class, true);
        Iterator iter = ext.iterator();
        while (iter.hasNext()) {
            Transfer t = (Transfer) iter.next();
            threads.add(startConcurrentTransfer(JDOHelper.getObjectId(t)));
        }
        tx.commit();
        while (!threads.isEmpty()) {
            Thread td = (Thread) threads.removeFirst();
            try {
                td.join();
            } catch (InterruptedException e) {
            }
        }
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
    // Check the results
    pm = pmf.getPersistenceManager();
    pm.setProperty(PropertyNames.PROPERTY_SERIALIZE_READ, "true");
    tx = pm.currentTransaction();
    try {
        tx.begin();
        Extent ext = pm.getExtent(Transfer.class, true);
        Iterator iter = ext.iterator();
        while (iter.hasNext()) {
            Transfer transfer = (Transfer) iter.next();
            assertTrue(transfer.isBooked());
        }
        ext = pm.getExtent(Account.class, true);
        iter = ext.iterator();
        while (iter.hasNext()) {
            Account acct = (Account) iter.next();
            String name = acct.getName();
            if ("alice".equals(name)) {
                assertEquals(700, acct.getSaldo());
            } else if ("berta".equals(name)) {
                assertEquals(100, acct.getSaldo());
            } else if ("charly".equals(name)) {
                assertEquals(200, acct.getSaldo());
            } else {
                assertFalse("unexpected account name: " + name, true);
            }
        }
        tx.commit();
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
}
Also used : Account(org.datanucleus.samples.concurrency.Account) Transaction(javax.jdo.Transaction) PersistenceManager(javax.jdo.PersistenceManager) Extent(javax.jdo.Extent) Transfer(org.datanucleus.samples.concurrency.Transfer) Iterator(java.util.Iterator) LinkedList(java.util.LinkedList)

Example 2 with Account

use of org.datanucleus.samples.concurrency.Account in project tests by datanucleus.

the class ConcurrencyTest method performTransfer.

public void performTransfer(Transfer t) {
    PersistenceManager pm = JDOHelper.getPersistenceManager(t);
    pm.setProperty(PropertyNames.PROPERTY_SERIALIZE_READ, "true");
    Transaction tx = pm.currentTransaction();
    int amount = t.getAmount();
    try {
        // Retrieve from and to Accounts using this PM - should lock the objects in the database
        Account from = getAccountByName(pm, t.getFromAccount());
        Account to = getAccountByName(pm, t.getToAccount());
        int fromSaldo = from.getSaldo() - amount;
        from.setSaldo(fromSaldo);
        pm.flush();
        try {
            // make sure the other transaction comes here concurrently
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        // Update "to" account
        int toSaldo = to.getSaldo() + amount;
        to.setSaldo(toSaldo);
        // Update Transfer as "booked"
        t.setBooked(true);
        tx.commit();
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
}
Also used : Account(org.datanucleus.samples.concurrency.Account) Transaction(javax.jdo.Transaction) PersistenceManager(javax.jdo.PersistenceManager)

Example 3 with Account

use of org.datanucleus.samples.concurrency.Account in project tests by datanucleus.

the class ConcurrencyTest method getAccountByName.

private Account getAccountByName(PersistenceManager pm, String acct) {
    Query query = pm.newQuery("SELECT FROM " + Account.class.getName() + " WHERE name == :acct");
    Collection result = (Collection) query.execute(acct);
    Iterator iter = result.iterator();
    Account account = (Account) (iter.hasNext() ? iter.next() : null);
    query.closeAll();
    return account;
}
Also used : Account(org.datanucleus.samples.concurrency.Account) Query(javax.jdo.Query) Iterator(java.util.Iterator) Collection(java.util.Collection)

Aggregations

Account (org.datanucleus.samples.concurrency.Account)3 Iterator (java.util.Iterator)2 PersistenceManager (javax.jdo.PersistenceManager)2 Transaction (javax.jdo.Transaction)2 Collection (java.util.Collection)1 LinkedList (java.util.LinkedList)1 Extent (javax.jdo.Extent)1 Query (javax.jdo.Query)1 Transfer (org.datanucleus.samples.concurrency.Transfer)1