EJB 计时器忽略 TransactionTimeout
EJB timer ignores TransactionTimeout
我耳边有一个 EJB 计时器,部署在 JBoss 6.4 上。在 99% 的所有情况下,计时器都可以正常工作,但有时它需要太长时间才能完成并抛出 PersistenceException: Transaction was rolled back in a different thread!
.
我发现这是由于事务超时值太低造成的。我不想编辑默认值,而是要覆盖特定于方法的超时。为了解决这个问题,我将功能分为两种方法:一种方法用 @Timeout
注释,另一种方法真正起作用。
这是我的计时器实现:
@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();
}
}
但是,计时器似乎忽略了 TransactionTimeout,因为它在 5 分钟(默认值)后仍然超时。如何覆盖默认超时以确保计时器完成作业?
不确定我是否理解正确。
从您的代码来看,您似乎是从 @Timeout 方法调用 workInNewThread() ,但是有一个带有 Tx 属性的方法 cleanup()。
我猜您是从@Timeout 调用同一个bean 中的方法。
但在这种情况下,@TxAttribute 和 TxTimeout 注释都不会生效,因为容器不控制内部方法调用。
您需要使用不同的 EJB 或自引用来让控制器完成这项工作。
另一种选择是直接注释超时方法。
我耳边有一个 EJB 计时器,部署在 JBoss 6.4 上。在 99% 的所有情况下,计时器都可以正常工作,但有时它需要太长时间才能完成并抛出 PersistenceException: Transaction was rolled back in a different thread!
.
我发现这是由于事务超时值太低造成的。我不想编辑默认值,而是要覆盖特定于方法的超时。为了解决这个问题,我将功能分为两种方法:一种方法用 @Timeout
注释,另一种方法真正起作用。
这是我的计时器实现:
@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();
}
}
但是,计时器似乎忽略了 TransactionTimeout,因为它在 5 分钟(默认值)后仍然超时。如何覆盖默认超时以确保计时器完成作业?
不确定我是否理解正确。 从您的代码来看,您似乎是从 @Timeout 方法调用 workInNewThread() ,但是有一个带有 Tx 属性的方法 cleanup()。
我猜您是从@Timeout 调用同一个bean 中的方法。 但在这种情况下,@TxAttribute 和 TxTimeout 注释都不会生效,因为容器不控制内部方法调用。 您需要使用不同的 EJB 或自引用来让控制器完成这项工作。 另一种选择是直接注释超时方法。