0

我有一個名爲NotificationService的實用程序服務。它沿着MailService的方向發展,服務層具有NotificationService接口(定義服務)和NotificationServiceUtil類(靜態提供服務),並且我有一個提供NotificationServiceImpl(實現)的impl層。然後,我在ext-spring.xml中註冊該服務:如何在沒有服務構建器的情況下在liferay transactional中創建服務方法

<bean id="org.mitre.asias.portal.notification.service.NotificationService" 
    class="org.mitre.asias.portal.notification.service.impl.NotificationServiceImpl"> 
    ... 
    </bean> 
    <bean id="org.mitre.asias.portal.notification.service.NotificationServiceUtil" 
    class="org.mitre.asias.portal.notification.service.NotificationServiceUtil"> 
    <property name="service" 
     ref="org.mitre.asias.portal.notification.service.NotificationService" /> 
    </bean> 

一切都按預期工作,直到我嘗試將事務混合到一起。我在NotificationServiceImpl一個方法需要進行交易:

public void sendAndUpdate(Message message, List<Event> eventsToUpdate) throws SystemException, MessagingException { 
    for (Event event : eventsToUpdate) { 
     eventLocalService.updateEvent(event); 
    } 
    Transport.send(message); 
} 

的想法是,如果由於某種原因,消息發送失敗,則更改模型對象將被回滾,所以我可以重試稍後發送。我嘗試使用以下注釋:

@Transactional(isolation = Isolation.PORTAL, 
     rollbackFor = { PortalException.class, SystemException.class, MessagingException.class }) 

但它沒有采取。我嘗試將該註釋移動到NotificationService接口,但仍然沒有骰子。我在org.hibernate.transaction.JDBCTransaction上啓用了調試日誌記錄,並且可以看到對該方法的調用從未啓動事務,但啓動併爲循環中的每個updateEvent調用提交了一個事務。

挖掘到源,看來Liferay的有一個bean後處理器稱爲ServiceBeanAutoProxyCreator其中有這樣的代碼:

... 
protected Object[] getAdvicesAndAdvisorsForBean(
     Class<?> beanClass, String beanName, TargetSource targetSource) 
    throws BeansException { 

    if (beanName.endsWith(_SERVICE_SUFFIX)) { 
     return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS; 
    } 
    else { 
     return DO_NOT_PROXY; 
    } 
} 

private static final String _SERVICE_SUFFIX = "Service"; 
... 

這使得它看起來好像每個bean的名字與服務(如我的豆確實結束:...id="org.mitre.asias.portal.notification.service.NotificationService"...)應該被包裹在ServiceBeanAopProxy這將根據服務構建器添加事務通知產生base-spring.xml

<bean class="com.liferay.portal.spring.aop.ServiceBeanAutoProxyCreator"> 
    <property name="methodInterceptor" ref="serviceAdvice" /> 
</bean> 
<bean class="com.liferay.portal.spring.context.PortletBeanFactoryCleaner" /> 
<bean class="com.liferay.portal.spring.context.PortletBeanFactoryPostProcessor" /> 
<bean class="com.liferay.portal.spring.bean.BeanReferenceAnnotationBeanPostProcessor" /> 
<bean id="portletClassLoader" class="com.liferay.portal.kernel.portlet.PortletClassLoaderUtil" factory-method="getClassLoader" /> 
<bean id="servletContextName" class="com.liferay.portal.kernel.portlet.PortletClassLoaderUtil" factory-method="getServletContextName" /> 
<bean id="basePersistence" abstract="true"> 
    <property name="dataSource" ref="liferayDataSource" /> 
    <property name="sessionFactory" ref="liferaySessionFactory" /> 
</bean> 
<bean id="serviceAdvice" class="com.liferay.portal.monitoring.statistics.service.ServiceMonitorAdvice"> 
    <property name="monitoringDestinationName" value="liferay/monitoring" /> 
    <property name="nextMethodInterceptor" ref="asyncAdvice" /> 
</bean> 
<bean id="asyncAdvice" class="com.liferay.portal.messaging.async.AsyncAdvice"> 
    <property name="defaultDestinationName" value="liferay/async_service" /> 
    <property name="nextMethodInterceptor" ref="threadLocalCacheAdvice" /> 
</bean> 
<bean id="threadLocalCacheAdvice" class="com.liferay.portal.cache.ThreadLocalCacheAdvice"> 
    <property name="nextMethodInterceptor" ref="transactionAdvice" /> 
</bean> 
<bean id="transactionAdvice" class="com.liferay.portal.spring.transaction.TransactionInterceptor"> 
    <property name="transactionAttributeSource" ref="transactionAttributeSource" /> 
    <property name="transactionManager" ref="liferayTransactionManager" /> 
</bean> 
<bean id="transactionAttributeSource" class="com.liferay.portal.spring.transaction.AnnotationTransactionAttributeSource" /> 

沒有任何人有任何想法我怎麼能做這個工作?

我在Tomcat 6.0.32容器中使用Liferay 6.0 EE sp2。

回答

0

嘗試移動@Transactional註釋上的接口(未在接口的方法)

Liferay的包裹在其中豆類名以服務結束(取決於bean的名稱不是類名)的交易。

此外,問題可能出現在代碼的位置。你在哪裏定義你的bean?我想在extplugin?如果您希望在沒有服務構建器的情況下將Liferay事務擴展到您自己的portlet中,它可能會變得棘手。但是,應該可以在6.1中共享Liferay spring上下文。

相關問題