【发布时间】:2014-05-11 11:21:26
【问题描述】:
我有以下服务,基本上是在特定的时间间隔安排执行以下操作:
- 获取要下载的网址列表
- 执行下载
- 将它们保存到磁盘
- 将下载产生的实体保留在磁盘上的位置
这些下载都可能需要 1-2 小时。根据您将在我的课程布局中看到的内容以及据我所知,我在整个预定服务期间都永久处于事务中。
@Stateless
public class TimedService {
@EJB
private Facade facade;
@Schedule(hour="*/12")
public void run() {
List<String> urls = getAllUrls();
urls.forEach(u -> {
facade.downloadFromUrl(u);
});
}
}
@Stateless
public class Facade {
@EJB
private Dao dao;
public void downloadFromUrl(String url) {
//this is the download part that may take a couple of minutes
byte[] bytes = NetUtils.getByteArrayFromUrl(url);
//if download was succesfull
if(bytes != null) {
//save the filename to disk
String fileName = createFileName(url);
Files.write(fileName, bytes);
//save entity to the database with the fileName location
Entity e = new Entity(fileName);
dao.merge(e);
}
}
}
所以基本上要么 Wildfly 将事务超时(默认为 5 分钟),要么我将其更改为像 24 小时内超时这样的巨大事件。
如果我理解正确,即使 Facade#downloadFromUrl 事务中的超时可能不会被触发,因为单个下载不会持续那么长时间,我仍处于 TimedService#run 事务中,该事务将在整个持续时间内打开 需要所有下载才能完成。
那么除了将事务超时调整到一个巨大的数字之外,还有更好的方法吗?
【问题讨论】:
-
好吧,让 run() 方法不是事务性的。
-
我该怎么做?我对 TransactionAttribute 表示法不是很熟悉。
-
这就是文档存在的原因:docs.oracle.com/javaee/6/api/javax/ejb/…
标签: java transactions ejb