インターネット経由で大量のデータを送信する J2EE アプリケーション (weblogic、oracle) があります。ただし、トランザクションのタイムアウトが発生します。そこで、次の方法でアプリケーションをリファクタリングしました。
タイマーにはコンテナー管理のトランザクションがありますが、コールバックには NOT_SUPPORTED フラグがあります。
@Stateless(mappedName = "TransferTimer", name = "TransferTimer")
public class TransferTimer implements ITransferTimerLocal {
@Timeout
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void timeoutCallback(final Timer timer) {
vo = transferController.prepareTransfer();
if (vo != null) {
transferController.sendData(vo);
transferController.finishTransfer(vo);
}
..
Bean 管理のトランザクションで新しい Bean が導入されました。長時間実行される方法は、トランザクションとデータベースをまったく処理しません。
@Stateless
@TransactionManagement(value= TransactionManagementType.BEAN)
public class TransferController implements TransferControllerLocal {
public TransferVO prepareTransfer() {
TransferVO vo = null;
try {
userTransaction.begin();
..
// no transactions must be there - it may take too much time
public void sendData(TransferVO vo) {
client.sendFile(vo.getOrder(), vo.getArchive());
}
client.sendFile() が正常に終了すると、 TransactionTimeout 例外がスローされます。
Caused by: weblogic.transaction.internal.TimedOutException: Transaction timed out after 61 seconds
BEA1-263D00276AD109CA0CA4
at weblogic.transaction.internal.ServerTransactionImpl.wakeUp(ServerTransactionImpl.java:1788)
at weblogic.transaction.internal.ServerTransactionManagerImpl.processTimedOutTransactions(ServerTransactionManagerImpl.java:1676)
at weblogic.transaction.internal.TransactionManagerImpl.wakeUp(TransactionManagerImpl.java:1988)
at weblogic.transaction.internal.ServerTransactionManagerImpl.wakeUp(ServerTransactionManagerImpl.java:1586)
at weblogic.transaction.internal.WLSTimer.timerExpired(WLSTimer.java:35)
私はこれを理解できません。なぜ失敗するのですか?