我想了解Optimistic Lock
中的Hibernate
做了什么以及如何正确使用它。
我的第一个问题是,当一个Thread
尝试保留Object
而另一个Object
同时已经改变了同一个Thread
的状态时,它是否只关心抛出异常,或者它是否关心两个修改是否正确保存?当对象链被更新并且每个database-model
尝试改变的部分不同时,最后一个至少是真的吗?
我想举一个例子,以便让我对真实场景的问题具有可理解性。这是一个设计糟糕的@Entity
public class Order{
@OneToMany
private User_Order user_Order;
}
@Entity
public class User_Order{
@OneToMany
private Product product;
}
,但它用于描述问题:
假设有一个具有以下实体:
Order
在单词中,User-Orders
包含多个User-Order
,每个Products
的数量为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);
。假设每个线程都使用以下代码:
Object
很明显,如果一个线程更新order
database-model
,那么其他线程持久化的数据将返回其初始状态,因为最后一个线程不知道有关更新的任何信息。 (正如已经承认的那样,这是设计不良的Threads
)
1)如果多个Optimistic Lock
可以同时执行此代码,那么确保并发安全的最佳方法是什么?可以在此处应用Thread
吗?
2)如果一个{{1}}(用户)也可以修改理论上属于其他用户的数据,那么上一个问题的答案是什么?
答案 0 :(得分:1)
当您使用支持事务的数据库时,并发访问问题会远离Java代码(如果您正确使用数据库访问工具),应该由数据库和锁定策略处理。
据我所知,你读过这篇文章: http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html
如果没有 - 请先阅读。
主要思想是,当你使用hibernate时,你通过Session对象与数据库进行通信,这不是线程安全的,应该是线程限制的,这意味着 - 不要在线程之间使用它,每个线程的会话。如果你这样做,很棒 - 你需要的只是决定你将使用哪种策略进行锁定 - 乐观或悲观锁定。
乐观更加用户友好,因为例如所有用户都可以读取和编辑数据,但是当两个人同时编辑数据时,第一个人获胜,第二个人必须重新输入他的数据。没关系,当你有一个带有2个文本框的小表单时,但不是真的,当你要填充5000个字符的文本区域时。在第二种情况下,您希望使用悲观锁定并使用适合您需要的锁定级别。