我正在维护看起来像这样的代码
@Asynchronous
@TransactionTimeout(value = 1, unit = TimeUnit.HOUR)
public void downloadFile(Long fileId) {
//This method takes more than 1hour
service.download(fileId)
//this method should be called even when download finished with error
service.fileDownloadedFinishedNotification(fileId);
}
这只是一个示例代码,我们向fileDownloadedFinished
传递了要显示的消息,并在其中希望将进程标记为已完成,但有错误/成功。
因此,正如您在下载中看到的那样,我们可以获得超时,此后将不会调用fileDownloadedFinishedNotification
,因为事务因超时而失败。
我正在考虑将通知提取到其他方法,并这样调用:
@Asynchronous
@TransactionTimeout(value = 1, unit = TimeUnit.HOUR)
public Future<String> downloadFile(Long fileId) {
//This method takes more than 1hour
service.download(fileId)
return new AsyncResult<String>("Test");
}
public void example(){
long id = 15;
String msg = "default stuff";
try {
msg = downloadFile(id).get();
}
catch (Exception e) {
e.printStackTrace();
}
service.fileDownloadedFinishedNotification(fileId, string);
}
但是我不确定这是个好主意,还是有其他一些功能,可以在超时后调用。像onTimeout
之类的东西。
答案 0 :(得分:1)
一些注意事项:
downloadFile
。fileDownloadedFinishedNotification
时,当前事务将被中止,因此对已事务处理的资源(数据库等)的所有操作都将回滚(您可能必须在专用事务中调用该方法) (例如,用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
注释您的方法。download
方法通过网络检索内容,除非您最后通过专用的JCA adapter
访问此内容,否则事务超时不会引发任何异常,Transaction reaper
仅标记当前事务中止并释放相关资源,但是does not interrupt the thread,仅随后对MANAGED资源(数据源,JMS等)的访问将引发异常。EJBContext.getRollbackOnly()
或通过对任何托管资源进行虚拟访问来定期检查其状态。答案 1 :(得分:1)
有多种方法可以实现您想要的,但是正确的实现需要更多有关您对应用程序更改的访问级别的信息。 在很多地方都解释了事务传播,但是让您在EJB容器中运行应用程序,我将从这里开始:
https://docs.oracle.com/javaee/6/tutorial/doc/bncih.html
我会读完所有章节,但最适合您的情况的是此处的容器托管交易:
https://docs.oracle.com/javaee/6/tutorial/doc/bncij.html
现在假设您拥有完全访问权限,并且可以按照我将要实现的方式更改数据库结构,即:
希望有帮助。抱歉,我没有为示例打码,但我想您将有足够的起点。
欢呼