简体   繁体   中英

Optimistic Lock - Concurrency issue with Hibernate

I am trying to understand what Optimistic Lock in Hibernate does and how is it to be used properly.

My first question is whether it only cares that an exception is thrown when one Thread tries to persist an Object while another has in the meantime already changed the state of the same Object , or does it care that both modifications are saved correctly? Is the last at least true when chains of Objects are updated and the parts which each Thread tries to alter are different?

I would like to present an example in order to make my question on a true scenario comprehensible. It is a bad-designed database-model but it serves to depict the issue:

Assuming one has the following Entities:

@Entity
public class Order{

@OneToMany
private User_Order user_Order;

}


@Entity
public class User_Order{

@OneToMany
private Product product;

}

In words an Order holds a number of User-Orders and each User-Order has a number of Products . Assuming that each Thread excecutes the following code:

Order order = (Order) session.get(Order.class, 1);
//some other code...
Set<User_Order> userOrders = order.getUserOrder();
User_Order myUserOrder = //find my User_Order
List<Products> products = myUserOrder.getProducts();
//modify myUserOrder 
//modify products
session.update(order);

It is apparent that if a Thread updates the Object order , then the data which was persisted by other Threads return to its initial state, because the last Thread does not know anything about the update. (As already admitted, it is the result of a bad-designed database-model )

1) What is the best way to ensure concurrency safety in case that several Threads can excecute this code simultaneously ? Can an Optimistic Lock be applied here?

2) What is the answer to the previous question if one Thread (User) can modify also the data of which theoritically belong to other Users?

When you work with database that supports transactions the problem of concurrent access moves away from java code (if you use database access tools correctly) and should be handled by database and locking strategy.

I understand that you read this article for instance: http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html

If not - read it first.

The main idea is, that when you use hibernate, you communicate with database through Session object, which is not thread-safe and should be thread confined, which means - don't use it between threads, session per thread. If you do that, great - all you need is is to decide which strategy will you use for locking - optimistic, or pessimistic locking.

Optimistic is more user friendly, because for instance all user can read and edit the data, but when two guys will at the same time edit the data, the first one wins, and the second one has to reenter his data. It's ok, when you have a small form with 2 text boxes, but not really, when you have 5000 characters text area to fill. In second case you want to use pessimistic locking and use the level of locking that suits your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM