![](/img/trans.png)
[英]Not able to catch org.hibernate.StaleObjectStateException
[英]Optimistic locking and org.hibernate.StaleObjectStateException:
我只是在嘗試樂觀鎖定。
我有以下課程:
@Entity
public class Student {
private Integer id;
private String firstName;
private String lastName;
private Integer version;
@Version
public Integer getVersion() {
return version;
}
//all other getters ommited.
}
現在我正在抓住其中一個學生並嘗試同時更新其屬性。
Thread t1 = new Thread(new MyRunnable(id));
Thread t2 = new Thread(new MyRunnable(id));
t1.start();
t2.start();
和MyRunnable內部:
public class MyRunnable implements Runnable {
private Integer id;
@Override
public void run() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Student student = (Student) session.load(Student.class, id);
student.setFirstName("xxxx");
session.save(student);
session.getTransaction().commit();
System.out.println("Done");
}
public MyRunnable(Integer id){
this.id = id;
}
}
第一個事務成功更新對象和第二個事務拋出的情況:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.vanilla.entity.Student#1]
還行吧。
我的問題是:1)如果我希望第二個交易什么都不做而且不拋出任何異常,我該怎么辦?
2)如果我希望第二個事務覆蓋第一個事務更新的數據,我該怎么辦?
謝謝。
我試着回答你的問題:
您使用樂觀鎖定。 因此,您希望在版本沖突時拋出OptimisticLockException
- 但您可以捕獲它並且不執行任何操作。 您不能將其關閉一秒(無論這意味着什么)事務,因為您不知道是否會發生版本沖突(這是樂觀鎖策略的本質: 樂觀假設是版本沖突不會經常發生)
如果發生OptimisticLockException
,您基本上有2個選項:
如果您有並發更新,問題是如何或誰將決定哪個狀態是實際的“正確”(表示最新的)。 只要保證一致性,我就不在乎了。
我有同樣的例外。 一旦我改變了它就解決了
@GeneratedValue(strategy = GenerationType.SEQUENCE)
至
@GeneratedValue(strategy = GenerationType.AUTO)
在我的實體。
我的應用在MySQL服務器上運行。
免責聲明:這是一個建議; 我自己沒試過。
我完全放棄了version字段,並在XML映射中將此實體樂觀鎖定策略設置為“none”:
<class name="Student" optimistic-lock="none"/>
或作為注釋:
@Entity(optimisticLock=OptimisticLockType.NONE)
這些是特定於Hibernate的,你不會在JPA規范中找到它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.