工作共享EntityManagers吗 - Play!框架

3

假设我有三个正在运行的工作,其中有两个是相同的...因此:

CrawlJob job1 = new CrawlJob();
CrawlJob job2 = new CrawlJob();
CurrentJob job3 = new CurrentJob();
job1.now()
job2.now()
job3.now()

如果我在job1中执行以下操作:

JPA.em().flush();
JPA.em().clear();

这是否也会分离job2和job3当前正在处理的所有实体?也就是说,如果我在job2/job3中传递了一个在数据库中查找的实体/模型对象,那么job2/job3是否有可能因为该对象刚刚从会话中分离而出现问题?

同样地,假设我在job1中执行以下操作:

long id = 123
User user1 = new User(id);
user1.save();

接着,在job2或job3中进行如下操作:

User user2 = User.findById(id);

用户2将会等于"null"还是等于"user1"?这意味着,即使用户1尚未被刷新/提交到数据库中,作业2或作业3是否能够通过ID查找它?

我认为这两个问题的核心是:作业(无论它们是相同作业的实例还是不同作业)是否共享EntityManagers,因此.em().flush()、.em().clear()或.em().getTransaction().commit()或Model.save()是否会同时影响所有的作业?

1个回答

3

Jobs会启动自己的JPA事务,直到事务完成,您的实体才会真正被持久化。

因此,如果job1尚未完成事务,job2将无法看到job1所做的更改,除非job2在加载实体时job1已经完成。

如果您希望在job1仍在运行时提交数据,可以在job1中提交事务,然后使用类似以下内容开始新事务:

    JPA.em().getTransaction().commit();
    JPA.em().getTransaction().begin();
    JPA.em().flush();
    JPA.em().clear();

假设job1和job2(同一个Job的两个实例)调用“doJob()”中的相同方法,名为processQueue()。所以如果在'processQueue(){}'中我执行'JPA.em().getTransaction',您是说根据调用processQueue()的是job1还是job2,会返回不同的Transaction?同样,似乎您是在说在job1中进行'JPA.em().clear'将不会对当前可能已附加在job2中的实体产生任何影响。 - HelpMeStackOverflowMyOnlyHope
在你提供的例子中,为什么要在JPA.em().getTransaction().commit()之后执行JPA.em().flush()?难道不是commit()已经将所有内容与数据库同步并刷新了,以便能够写出吗? - HelpMeStackOverflowMyOnlyHope
谢谢你的回答。我有很多需要立即保存的实体。因此,我将这段代码放入一个名为“saveEntities”的void中,并在需要立即更新的任何地方调用它。 - dreampowder
1
我注意到有时在我的作业中使用纯JDBC进行数据插入更为简单。这样可以获得更好的性能和对数据持久性的更多控制。 - emt14

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接