У меня простые отношения ко многим в JPA.для обсуждения предположим, что мои сущности - это Персона и Телефон, где Персона может иметь много Телефонов (номеров).
оба объекта могут обновляться независимо, и у меня высокий уровень параллелизма.мне нужно реализовать пессимистическую блокировку для обоих объектов (в любом случае, это мое предположение).
поэтому в моем коде я делаю что-то вроде
em.getTransaction().begin();
Person p = em.find(Person.class, id, LockModeType.PESSIMISTIC_WRITE);
...
и аналогично для телефона
em.getTransaction().begin();
Phone ph = em.find(Phone.class, id, LockModeType.PESSIMISTIC_WRITE);
...
обратите внимание, что в транзакции Person зависимый объект Phone может быть обновлен, и наоборот.вариант использования - это флаг lastModified.Обновление телефона обновляет отметку времени lastModified в Person, и, наоборот, обновление отметки времени lastModified в Person обновляет флаг lastModified в Phone (это делается через прослушиватели сущностей).Я понимаю, что сценарий использования немного надуман, но попробуйте проигнорировать это.
приведенный выше код приводит к мертвой блокировке.
INFO: [EL Warning]: 2011-06-30 08:41:52.65--ServerSession(122902)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLTransactionRollbackException: A lock could not be obtained within the time requested
Error Code: 30000
В настоящее время моя гипотеза заключается в том, что транзакция Person захватывает блокировку для Person A, а затем пытается получить блокировку для Phone 1. В то же время транзакция Phone захватывает блокировку для Phone.1, побеждая транзакцию Person, затем пытается получить блокировку для тупика Person A.
это всего лишь предположение, основанное на наивном понимании того, как работают транзакции, и, по сути, нулевое знание о том, как объектБлокировка работает в JPA.я бы подумал , что объект и его иждивенцы заблокированы атомарно ... вот что должно произойти, чтобы это сработало.
есть мысли?
одна идея, которую нужно исправитьэто то, что я буду пытаться забыть об обновлении зависимых объектов в той же транзакции.вместо этого откройте новую транзакцию после первого завершения, чтобы обновить зависимый объект.