JBoss 6.4にデプロイされた耳にEJBタイマーがあります。すべてのケースの99%で、タイマーはうまく動作しますが、終了するには時間がかかりすぎて、PersistenceException: Transaction was rolled back in a different thread!
がスローされることがあります。EJBタイマーはTransactionTimeoutを無視します
これは、トランセイションのタイムアウト値が低すぎることが原因であることが判明しました。私はデフォルト値を編集するのではなく、メソッド固有のタイムアウトをオーバーライドします。これを解決するために、機能を2つのメソッドに分割しました.1つのメソッドに@Timeout
と注釈を付け、実際には機能させます。ここで
は私のタイマーimplememntationです:
@Singleton
public class MyTimer implements SomeTimerInterface {
@EJB
private SomeManager myManager;
@Resource
private TimerService timerService;
private Timer timer;
@Override
public void startTimer() {
// Timer scheduled to fire every 7th minute
ScheduleExpression schedule = new ScheduleExpression();
schedule = schedule.hour("*").minute("*/7").second("00");
TimerConfig config = new TimerConfig();
config.setPersistent(false);
timer = timerService.createCalendarTimer(schedule, config);
}
@Timeout
@AccessTimeout(value = 20, unit = TimeUnit.MINUTES)
public void handleTimeout() {
workInNewThread();
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@TransactionTimeout(unit = TimeUnit.SECONDS, value = 900)
public void workInNewThread() {
// This can take anything from 1 sec to 15 min.
List<Object> objects = myManager.getAllTheDatabaseObjects();
}
}
ただし、タイマーは5分(デフォルト値)の後からそれはまだ時間としてTransactionTimeoutを無視しているようです。タイマーがジョブを終了したことを確認するために、デフォルトのタイムアウトを無効にするにはどうすればよいですか?
申し訳ありませんが、私は例を書いたときにわかりやすくするためにメソッドの名前を変更しました。 cleanupとworkInNewThreadは同じメソッドです。私は今私の投稿を編集しました。 – Pphoenix
私は自分のクラスのプロキシを取得し、そのオブジェクトのメソッドを呼び出す必要がありますか?私はこのスレッドで類似したものを見つけました。https://developer.jboss.org/thread/165400?tstart=0 – Pphoenix
私はちょうどこれをテストして、完璧に動作しました。別のEJBを使用して、タイマー管理とビジネスロジック間の懸念を分離しました。 – Pphoenix