0

NotificationService というユーティリティ サービスがあります。サービス層には NotificationService インターフェイス (サービスを定義する) と NotificationServiceUtil クラス (サービスを静的に提供する) があり、NotificationServiceImpl (実装) を提供する impl 層があるという点で、MailService の方針に従います。次に、サービスを ext-spring.xml に登録しました。

  <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 には次のServiceBeanAutoProxyCreatorコードを持つ Bean ポスト プロセッサが呼び出されているようです。

...
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";
...

これにより、名前が Service で終わるすべての Bean (私の Bean のように : ) は、サービス ビルダーによって生成されたトランザクション アドバイスを追加する...id="org.mitre.asias.portal.notification.service.NotificationService"...にラップする必要があるように見えます。ServiceBeanAopProxybase-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 を使用しています。

4

1 に答える 1

0

@transactional アノテーションを (インターフェースのメソッドではなく) インターフェースに移動してみてください。

Liferay は、名前が Service で終わる Bean にトランザクションをラップします (クラス名ではなく Bean 名に依存します)。

また、問題はコードの配置にある可能性があります。Bean をどこで定義しますか? 私はextpluginにあると思いますか?サービス ビルダーを使用せずに、独自のポートレットで Liferay トランザクションを拡張したい場合は、注意が必要です。ただし、Liferay スプリング コンテキストを 6.1 で共有できるはずです。

于 2013-03-05T20:42:28.887 に答える