akp
akp

Reputation: 1893

concurrency (stale data) problem in JPA

Let's say I have methods with following signature

Object getData(int id) {  
  //create a entity manager
  //get data frm db
  //return data
}

updateData() {
  Object obj = getData(id) 
  //get entity manager
  //start transcation tx
  //update
  //commit tx
}

Now will it cause concurrency issue? Can data be stale in worst case? E.g. if I getData and by the time I update, if someone updates the data will my updateData will have stale data? Now can i use following:Will i solve the problem?

Object getData(int id,Entitymanager em) {  

      //get data frm db using em
      //return data
    }

 updateData() {
      Object obj = getData(id) 
      //get entity manager em
      //start transcation tx
      //getdata using getData(id,em)
      //commit tx
    }

Upvotes: 3

Views: 2425

Answers (3)

kraftan
kraftan

Reputation: 6312

If two separate requests access updateData() concurrently you may get stale data. You may handle the staleness by locking the fetched data in updateData(). If you're using Hibernate as your JPA provider you can lock the data as follows:

updateData() {
    Object obj = getData(id);
    Session session = (Session) em.getDelegate();
    session.refresh(obj, LockMode.UPGRADE);
}

The refresh is necessary because it may happen that between the fetching and the locking of the data another transaction completes in updateData.

Please keep in mind that the entity manager used in getData and updateData must be the same.

Upvotes: 1

M.J.
M.J.

Reputation: 16656

There can also be a problem in multi-threaded environment, if multiple access the same piece of code at the same time, it can create lock, for this you can use row level locking technique, that will help you.check out the below link.

http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm

Upvotes: 1

GaryF
GaryF

Reputation: 24350

Yes, that can happen.

If you get an entity (version 1), someone else modifies it (creating version 2), then you modify version 1 and save it, any changes in version 2 will be lost.

To stop that from happening, use optimistic concurrency by adding a @Version attribute to your entity. If a commit has occurred between your get and update, an exception will be thrown. At the point you can choose your best option to deal with it.

Upvotes: 6

Related Questions