How to acheive concurrency in Hiberante ?


Consider a scenario in which multiple applications are accessing same database. It is likely that is a data or row is fetched by an application1 and
later on by application2 and application2 makes an update in DB and when application1 makes update then if finds that the old data is lost and not sure what
to do.
To maintain high concurrency and high scalability hibernate allows the concept of versioning.Version checking uses version numbers, or timestamps, to detect conflicting updates (and to prevent lost updates). Hibernate provides for three possible approaches to writing application
code that uses optimistic concurrency.
1) Application version checking: each interaction with the database occurs in a new Session and the developer is responsible for reloading all persistent instances from the database before manipulating them. This approach forces the application to carry out its own version checking to ensure conversation transaction isolation.
This approach is the least efficient in terms of database access.
// foo is an instance loaded by a previous Session
session = factory.openSession();
Transaction t = session.beginTransaction();
int oldVersion = foo.getVersion();
session.load( foo, foo.getKey() ); // load the current state
if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
foo.setProperty("bar");
t.commit();
session.close();

The version property is mapped using <version>, and Hibernate will automatically increment it during flush if the entity is dirty.
Clearly, manual version checking is only feasible in very trivial circumstances and not practical for most applications.

2) Extended session and automatic versioning : A single Session instance and its persistent instances are used for the whole conversation, known as session-per-conversation. Hibernate checks instance versions at flush time, throwing an exception if concurrent modification is detected. It’s up to the developer to catch and handle this exception.
The Session is disconnected from any underlying JDBC connection when waiting for user interaction. This approach is the most efficient in terms of database access. The application need not concern itself with version checking or with reattaching detached instances, nor does it have to reload instances in every database transaction.

// foo is an instance loaded earlier by the old session
Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start transaction
foo.setProperty("bar");
session.flush(); // Only for last transaction in conversation
t.commit(); // Also return JDBC connection
session.close(); // Only for last transaction in conversation

3)  Detached objects and automatic versioning: Each interaction with the persistent store occurs in a new Session. However, the same persistent instances are reused for each interaction with the database. The application manipulates the state of detached instances originally loaded in another Session and then reattaches them using Session.update(), Session.saveOrUpdate(), or Session.merge().
// foo is an instance loaded by a previous Session
foo.setProperty("bar");
session = factory.openSession();
Transaction t = session.beginTransaction();
session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
t.commit();
session.close();

Again, Hibernate will check instance versions during flush, throwing an exception if conflicting updates occurred.

4) Customizing automatic versioning
You may disable Hibernate’s automatic version increment for particular properties and collections by setting the optimistic-lock mapping attribute to false. Hibernate will then no longer increment versions if the property is dirty.
Legacy database schemas are often static and can’t be modified. Or, other applications might also access the same database and don’t know how to handle version numbers or even timestamps. In both cases, versioning can’t rely on a particular column in a table. To force a version check without a version or timestamp property mapping, with a comparison of the state of all fields in a row, turn on optimistic-lock=”all” in the <class> mapping
Sometimes concurrent modification can be permitted as long as the changes that have been made don’t overlap. If you set optimistic-lock=”dirty” when mapping the <class>, Hibernate will only compare dirty fields during flush

One thought on “How to acheive concurrency in Hiberante ?

  1. Pingback: JavaPins

Leave a comment