更新
Liferay 票已接受,开发中的解决方案:https ://issues.liferay.com/browse/LPS-82954
情况
我的上下文是通过liferay portlet 并行导入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;
}