Параллельный API LayoutLocalService.addLayout создает исключение StaleObjectStateException в LayoutSetLocalService
ОБНОВИТЬ
Билет на Liferay принят, решение в dev: https://issues.liferay.com/browse/LPS-82954
ситуация
Мой контекст - это параллельный импорт макетов liferay через портлет liferay; строить с весны. Когда я выполняю это в Liferay dxp; вызов API для добавления макета вызывает исключение StaleObjectStateException. ( https://github.com/liferay/liferay-portal/blob/d969e0e839db9ea64267f7bff0a76be93cd26fa0/portal-impl/src/com/liferay/portal/service/impl/LayoutLocalServiceImpl.java)
Это исключение возникает, когда API-интерфейс внутренне обновляет соответствующий LayoutSet (обновляя PageCount для той группы, в которую был добавлен макет, всего минуту назад).
Это не происходит в однопоточном исполнении!
действия
- Во-первых, я синхронизировал этот вызов.. без каких-либо лучших результатов
- Между тем я читал кое-что о том, что только синхронизация потоков не поможет, потому что сама транзакция может не находиться внутри блока синхронизированного выполнения. поэтому я также добавил транзакционную аннотацию... без лучших результатов
до сих пор я получил следующее понимание:
В LayoutSetLocalService.updatePageCount() имеется ошибка: обновленный LayoutSet не возвращается.. поэтому (с введенным Liferay 7/DXP) mvcc-версия LayoutSet не увеличивается.... но это не должно влиять на мою ситуацию ( https://github.com/liferay/liferay-portal/blob/7eb86ce5f6a7b2c9a405853a20fe81592e639219/portal-impl/src/com/liferay/portal/service/impl/LayoutSetLocalServiceImpl.java).
Кто-нибудь может дать мне подсказку, есть ли шанс заняться этим?
- Или это следствие оптимистической блокировки, и я должен жить с этим?
- я пропустил головоломку при создании темы? может быть какой-то странный.. настроить мой спящий сеанс... вещь?
Выдержки из кода
-> Доступен тестовый проект: https://github.com/andrebiegel/liferay-layout-issue.git
private static final Object layoutCreationLock = new Object();
synchronized (layoutCreationLock) {
newLayout = addLayoutApiCall(pageContext, serviceContext, typeSettings, friendlyURLMap);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Layout addLayoutApiCall(IPageContext pageContext, ServiceContext serviceContext, String typeSettings,
Map<Locale, String> friendlyURLMap) throws PortalException {
Layout newLayout;
newLayout = LayoutLocalServiceUtil.addLayout( pageContext.getProjectConfiguration().getUserId(), pageContext.getProjectConfiguration()
.getSiteId(), pageContext.isPrivatePage(), pageContext.getParentLayoutId(), pageContext
.getNamesMap(), pageContext.getTitleMap(), pageContext.getDescriptionMap(), pageContext
.getKeywordsMap(), pageContext.getRobotsMap(), pageContext.getPageType(), typeSettings,
pageContext.isHiddenPage(), friendlyURLMap, serviceContext );
return newLayout;
}
1 ответ
К сожалению, Liferay не исправит это. Билет был закрыт; объявлен как не вариант использования. Причина в том, что решение вызвало негативные последствия в другом случае использования. Таким образом, у Liferay, похоже, есть проблема с управлением транзакциями. Кстати, я также видел такие исключения при одновременном добавлении Expandos.