我只是在尝试乐观锁定。

我有以下类(class):

@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个选项:
  • 放弃更改(并可能刷新当前状态)
  • 仅刷新您的实体(实体)的版本,然后尝试再次提交

  • 问题是,如果有并发更新,则如何或由谁来决定哪个状态才是实际的“正确”状态(意味着最新状态)。只要保证一致性,我都不会在意。

    10-07 22:11