如何解决@Singleton EJB中的多个计时器抛出javax.ejb.ConcurrentAccessTimeoutException
我有一个计划单例,我在其中尝试管理多个日历计时器。每隔30分钟就会有一次我拨打的服务。但是,每天一次(例如,凌晨3点),我需要致电同一服务以执行其他操作。
主要问题-您在同一个Singleton中可以有多个计时器吗?
当我查看代码时,在我看来,在某个时候(凌晨3点),这两个计时器将发生冲突,并且我将收到ConcurrentAccessTimeoutException,并且其中一个不会运行。例如:
Caused by: javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0241: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on TestBean- could not obtain lock within 5000MILLISECONDS
也许如果我首先在PostConstruct中创建3AM计时器,它将更有可能运行并锁定every30计时器?但是,即使这是可能的,似乎a)小小的骗子b)让人碰运气。我可以忍受every30计时器不会在凌晨3点开始运行,但是单次运行不能错过,因为它是唯一一次运行。另一种选择是将every30计时器设置为与一天一次的计时器不同时运行的功能,但是再次设置为hokey。
这是我的代码:
@Singleton
@Startup
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class SomeScheduler
{
@Resource
private TimerService timerService;
@Inject
@ConfiguredProperty(key="scheduleExpression1",mandatory=false,defaultValue="minute=*/30; hour=*")
private ScheduleExpression scheduleExpression1;
@Inject
@ConfiguredProperty(key="scheduleExpression2",defaultValue="hour=3; dayOfWeek=*")
private ScheduleExpression scheduleExpression2;
private Timer timer1;
private Timer timer2;
@PostConstruct
private void postConstruct()
{
timer1 = timerService.createCalendarTimer(scheduleExpression1,new TimerConfig("every30",false));
timer2 = timerService.createCalendarTimer(scheduleExpression2,new TimerConfig("at3AM",false));
}
@Timeout
public void handler (Timer timer)
{
if (Objects.equals(timer.getInfo(),"every30"))
{
// Call Something
}
if (Objects.equals(timer.getInfo(),"at3AM"))
{
// Call Something else
}
}
}
解决方法
是的,同一Singleton中可以有多个计时器。
但是您必须通过以下方式注释您的Singleton,以关闭“容器管理的并发访问”:
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
,
默认情况下,@Singleton
Bean中的公共方法具有@Lock(WRITE)
。如果您需要一次同时运行多次相同的方法,并且可以避免竞争,那么可以在方法顶部添加注释@Lock(READ)
:
https://docs.oracle.com/cd/E19798-01/821-1841/gipsz/index.html
如果您在这种特定方法下无法满足比赛条件,则可以通过以下注释增加访问超时:@AccessTimeout
这将解决ConcurrentAccessTimeoutException。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。