Spring @Transactional Deadlock - PullRequest
       5

Spring @Transactional Deadlock

3 голосов
/ 31 октября 2011

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

  • Spring 3.0.5
  • Hibernate 3.5.6
  • MySql 5.1

Toсохранить запись в БД через Hibernate У меня есть следующий рабочий процесс

  1. отправить JSON {id:1,name:"test",children:[...]} в Spring MVC App и использовать Джексона для преобразования его в граф объектов (если это существующийэкземпляр JSON имеет правильный идентификатор записи в наборе БД

  2. сохранить объект в БД с помощью вызова уровня обслуживания (подробности ниже)

    • функция сохранения интерфейса уровня обслуживания SomeObjectService имеет аннотацию @Transactional с readOnly=false и распространением REQUIRED

    • реализация этого уровня обслуживания SomeObjectServieImpl вызываетМетод сохранения DAO

    • DAO сохраняет новые данные с помощью вызова слияния hibernate, например, hibernateTempate().merge(someObj)

    • hibernate merge загружает объектсначала из БД через SELECT

    • У меня есть EntityListener, который подключен к пружине (я использовалэтот метод Spring + EntityManagerFactory + Hibernate Listeners + Injection ) и слушает @PostLoad

    • Слушатель использует LockingServie для обновления одного поля someObjectустановить его как заблокированный (это на самом деле должно происходить только тогда, когда someObject загружается через вызовы Hibernate HQL, SQL или Criteria , но вызывается также при объединении)

    • LockingServie имеет функцию lock(someObj,userId), которая также аннотируется @Transactional с readOnly=false и REQUIRED

    • обновление происходит через вызов Query query = sess.createQuery("update someObj set lockedBy=:userId"); и затем query.executeUpdate();

    • после того, как слияние загрузило данные, оно начинается с обновления someObject и вставки соответствующих дочерних элементов (<= здесь, в этом случае, возникает тупик <strong>)

  3. вернуть результат JSON (включая недавно созданный идентификатор объекта) обратно клиенту.

Кажется, проблемадля меня первая

  1. запись загружается в транзакцию
  2. затем изменяется в другой (внутренней) транзакции
  3. и затем должен снова обновляться данными внешней транзакции, но не может обновляться, потому что она заблокирована.

Через MySQL

SHOW OPEN TABLES 

я вижу, что дочерняя таблица (которая является частью графа объектов) заблокирована.

Интересно, что тупик не возникает натаблица someObj , а точнее таблица, представляющая дочерний элемент.

Я немного растерялся здесь.Любая помощь более чем приветствуется.

Кстати, может, уровень изоляции может вытащить меня из этой проблемы здесь?

Ответы [ 2 ]

1 голос
/ 25 января 2012

Я закончил, используя @ Bozho's HibernateExtendedJpaDialect

что объясняется здесь >> Hibernate, spring, JPS и изоляция - пользовательская изоляция не поддерживается

Чтобы установить изоляцию на READ_UNCOMMITED

@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
public Seizure merge(Seizure seizureObj);

Не очень хорошее решение, я знаю, но, по крайней мере, это решило мою проблему.

Если кто-то хочет иметь подробное описание, пожалуйста, спросите ...

0 голосов
/ 20 ноября 2011

Я не знаю решения проблемы, но у меня не было бы метода транзакционной блокировки. Если вам вообще нужно что-то заблокировать вручную, сделайте это с помощью другого метода транзакционной службы.

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