Оптимистическая блокировка и org.hibernate.StaleObjectStateException: - PullRequest
6 голосов
/ 05 октября 2011

Я просто экспериментирую с оптимистической блокировкой.

У меня есть следующий класс:

@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) Что мне делать, если я хочу, чтобы вторая транзакция переопределяла данные, обновленные первой транзакцией.

Спасибо.

Ответы [ 3 ]

9 голосов
/ 06 октября 2011

Я попробую ответить на ваши вопросы:

  1. Вы используете оптимистическую блокировку. Итак, вы хотите, чтобы OptimisticLockException генерировалось при конфликте версий - но вы можете его перехватить и ничего не делать Вы не можете отключить его для второй (что бы это ни значило) транзакции, потому что вы не знаете, произойдет ли конфликт версий (в этом суть стратегии оптимистической блокировки: оптимистическое предположение состоит в том, что конфликт версий происходит не очень часто)

  2. Если происходит OptimisticLockException, у вас есть 2 варианта:

    1. отменить изменения (и, возможно, обновить текущее состояние)
    2. обновите только версию вашей сущности (сущностей) и попробуйте зафиксировать снова

    Проблема в том, как или кто должен решить, какое состояние является «правильным» (означает последнее), если у вас есть одновременные обновления. Пока согласованность гарантирована, мне все равно.

0 голосов
/ 19 мая 2017

У меня было такое же исключение. Это было решено, как только я изменил

@GeneratedValue(strategy = GenerationType.SEQUENCE)

до

@GeneratedValue(strategy = GenerationType.AUTO) 

в моей сущности.

Мое приложение работает на сервере MySQL.

0 голосов
/ 06 октября 2011

Отказ от ответственности: это предложение; Я сам не пробовал.

Я бы полностью оставил поле версии и установил для этой стратегии оптимистической блокировки сущностей значение «none» в сопоставлении XML:

<class name="Student" optimistic-lock="none"/>

или в качестве аннотации:

@Entity(optimisticLock=OptimisticLockType.NONE)

Это специфичные для Hibernate, вы не найдете их в спецификации JPA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...