Java 具有会话的异步服务
我有一个方法将调用一个存储函数。我希望它异步地完成它的工作。这就是我所拥有的,但似乎.doWork()从未启动,因为当我调用Java 具有会话的异步服务,java,hibernate,jdbc,Java,Hibernate,Jdbc,我有一个方法将调用一个存储函数。我希望它异步地完成它的工作。这就是我所拥有的,但似乎.doWork()从未启动,因为当我调用getDao.deleteAll()时,存储的函数没有运行 @Transactional public void delete() { final Session session = (Session) entityManager.getDelegate(); ExecutorService executorService
getDao.deleteAll()
时,存储的函数没有运行
@Transactional
public void delete()
{
final Session session = (Session) entityManager.getDelegate();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable()
{
@Override
public void run()
{
LOGGER.warn("starting");
session.doWork(new Work()
{
@Override
public void execute(Connection connection) throws SQLException
{
try
{
CallableStatement purgeArchived = connection.prepareCall("{call deleteAll()}");
purgeArchived.execute();
}
catch (SQLException exception)
{
LOGGER.warn("Failed to purge archive points. Reason: " + exception);
}
}
});
LOGGER.warn("stopping");
}
});
executorService.shutdown();
}
我看到记录器记录了
“启动”
,但它从未记录到“停止”
为什么会发生这种情况 请注意,当您有一个单独的线程时,@Transaction
是没有意义的,因为事务通常是线程绑定的
您需要在run()内从工厂获得一个新的entityManager
还可以使用@Async,它更干净
再次注意@Async
如果您想使某些工作异步,一般的经验法则是将其视为单个工作单元和单独的事务 尝试移动
final Session Session=(Session)entityManager.getDelegate()代码>也在run
方法中。只是尝试了一下,在executorService.shutdown()之后(!executorService.isTerminated()){}
使用时没有运气代码>。这将使当前线程等待ExecutorService
中的线程完成。这是出于测试目的,因为如果它在这里结束,则意味着问题出现在初始化此线程的主线程中。问题出现在:CallableStatement purgeArchived=connection.prepareCall(“{call deleteAll()}”);我把日志记录语句放在后面,在prepareCall被记录之后什么都没有。不确定原因..似乎连接正在关闭,而另一个线程仍在工作。这就是您在管理线程时遇到的问题,外部线程管理连接的打开和关闭。因此,当前我的DAO正在扩展GenericDAOJpa,它在其中创建实体管理器。你是说我应该在run()中创建一个新的@bhantolAdding一个新的实体管理器确实有效!但你能告诉我背后的原因吗?谢谢@bhantolAlso您是否建议使用@Async而不是@Transactional?或者两者都使用?@JennyC EntityManager不是线程安全的。在run()中添加getting EntityManager之所以有效,是因为它能够在该线程中获得一个新的EntityManager,而不是使用在父线程/另一个线程中创建的EntityManager。是的,在相同的方法上注释@Async
和@Transnational
。(交易是孤立的)