2014-06-08 65 views
0

我想了解中的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 。假设每个线程excecutes下面的代码:

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); 

显而易见的是,如果一个线程更新这是由其他线程坚持返回到其初始状态的Objectorder,然后将数据,因为最后一个线程不知道有关更新的任何信息。 (正如已经承认的那样,它是错误设计的结果database-model

1)如果多个Threads可以同时超出此代码,确保并发安全性的最佳方法是什么? Optimistic Lock可以在这里应用吗?

2)如果一个Thread(用户)也可以修改原来属于其他用户的数据,那么上一个问题的答案是什么?

回答

1

当您使用支持事务的数据库时,并发访问问题将远离Java代码(如果您正确使用数据库访问工具)并且应该由数据库和锁定策略来处理。

我明白你阅读这篇文章,例如: http://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html

如果没有 - 第一次读到它。

其主要思想是,当您使用hibernate时,您通过Session对象与数据库进行通信,该对象不是线程安全的并且应该是线程受限的,这意味着 - 不要在线程之间使用它,每个线程会话。如果你这么做,那么很好 - 你需要的是决定你使用哪种策略进行锁定 - 乐观或悲观的锁定。

乐观是更加用户友好的,因为例如所有用户都可以读取和编辑数据,但是当两个人同时编辑数据时,第一个数据会胜出,第二个数据必须重新输入数据。没关系,当你有一个有2个文本框的小表格,但不是真的,当你有5000个字符的文本区域来填充。在第二种情况下,您希望使用悲观锁定并使用适合您需要的锁定级别。