#java #hibernate #locking
#java #спящий режим #блокировка
Вопрос:
У меня есть метод сеансового компонента, который использует Hibernate для добавления дочернего элемента в индексированную коллекцию объекта. Однако, поскольку может быть несколько потоков, обращающихся к методу одновременно, в некоторых странных случаях случалось, что повторяющийся индекс будет назначен разным дочерним элементам (ошибка в режиме гибернации? Я не знаю).
Чтобы предотвратить это, я хотел бы попытаться заблокировать весь объект, а также его коллекцию, чтобы другие потоки не могли его изменять, пока другой поток обновляет его. Я знаю, что мы можем установить режим блокировки для объекта, но как насчет коллекции? Может ли он заблокировать любые другие транзакции от добавления нового дочернего элемента?
Пожалуйста, просветите меня! Заранее спасибо.
Ответ №1:
Может быть, вы могли бы попробовать использовать синхронизированные оболочки коллекции. Вы можете использовать статические методы в классе Collections (Коллекции). Например:
List<String> myList = Collections.synchronizedList(new List<String>());
Что касается блокировки на уровне объекта, синхронизированный блок кода, заблокированный на объекте, должен сделать свое дело.
synchronized (entityInstance)
{
...
}
Комментарии:
1. Я боюсь, что это заблокирует все коллекции этого типа, которые не обязательно принадлежат одному и тому же объекту. Я хочу заблокировать только ту коллекцию, которая принадлежит одному и тому же объекту.
2. Нет, это не так. Статические методы коллекций возвращают экземпляр синхронизированной коллекции. Эти коллекции синхронизируются на уровне экземпляра, А НЕ на уровне класса.
3. Спасибо за разъяснение. Но это приводит к вопросу о том, использует ли Hibernate один и тот же объект объекта, на который ссылается ссылка, между разными потоками в EJB…
4. У меня нет опыта работы с EJB, но hibernate возвращает тот же экземпляр в том же сеансе. Если все ваши потоки работают с одним и тем же объектом сеанса, то экземпляр entity должен быть общим.
5. Тогда, боюсь, нет. Методы EJB каждый раз открывают новый сеанс. И из документа hibernate они рекомендуют нам оставить управление параллелизмом в режиме гибернации и DB, поэтому я могу попытаться прочитать о стратегии блокировки…