How to prevent non-repeatable query results using persistence API in Java SE?

Tags: , , , , , , , , , , ,
Posted in dotnet, vb, vb.net | No Comments »

I am using Java SE and learning about the use of a persistence API (toplink-essentials) to manage entities in a Derby DB. Note: this is (distance learning) university work, but it is not ‘homework’ this issue crops up in the course materials and the tutors don’t have much to say about it.

I have two threads operating on the same set of entities. My problem is that every way I have tried, the entities within a query resultSet() (query performed within a transaction) in one thread can be modified so that the resultSet() is no longer valid for the rest of the transaction.

e.g. from one thread this operation is performed:

static void updatePrices(EntityManager manager, double percentage) {
    EntityTransaction transaction = manager.getTransaction();

    transaction.begin();
    Query query = manager.createQuery("SELECT i FROM Instrument i where i.sold = 'no'");
    List<Instrument> results = (List<Instrument>) query.getResultList();

    // force thread interruption here (testing non-repeatable read)
    try { Thread.sleep(2000); } catch (Exception e) { }

    for (Instrument i : results) {
        i.updatePrice(percentage);
    }
    transaction.commit();
    System.out.println("Price update commited");
}

And if it is interrupted from another thread with this method:

private static void sellInstrument(EntityManager manager, int id)
{
    EntityTransaction transaction = manager.getTransaction();
    transaction.begin();
    Instrument instrument = manager.find(Instrument.class, id);
    System.out.println("Selling: " + instrument.toFullString());
    instrument.setSold(true);
    transaction.commit();
    System.out.println("Instrument sale commited");
}

What can happen is that when the thread within updatePrices() resumes it’s query resultSet is invalid, and the price of a sold item ends up being updated to different price to that at which it was sold. (The shop wishes to keep records of items that were sold in the DB). Since there are concurrent transactions occuring I am using different EntityManagers for each thread (from the same factory).

Is it possible (through locking or some kind of context propagation) to prevent the results of a query becoming ‘invalid’ during a (interrupted) transaction? I have an idea that this kind of scenario is what Java EE is for, but what I want to know is whether its doable in Java SE.

View author profile: willjcroz
View Complete from the original – SackOverflow.com

Similar:

  1. How to make m2eclipse (Maven) point to the “persistence.xml” path ? Hi everybody, I working with Eclipse Helios, m2eclipse Maven plugin and Glassfish plugin. I edited the “pom.xml” file so that I can get the DerbyClient...
  2. Java: Difference betwen UserTransaction and EntityTransaction Title says it all: What is the difference between a UserTransaction and a EntityTransaction? My rudimentary understanding is that UserTransaction is used when JTA is...
  3. java DataOutputStream exception The exception is thrown in line 24 the second time I type something (after I have typed the host name) – server works right. Code...
  4. EJB3 – using 2 persistence units within a transaction (Exception: Local transaction already has 1 non-XA Resource) I am trying to use 2 persistence units within the same transaction in a JEE application deployed on Glassfish. The 2 persistence units are defined...
  5. java database connection retrieval I am using the code below to display the records from my database in the swing form. However, when I click on the button it...

Tags: , , , , , , , , , , ,

Leave a Reply