Java 具有会话的异步服务

Java 具有会话的异步服务,java,hibernate,jdbc,Java,Hibernate,Jdbc,我有一个方法将调用一个存储函数。我希望它异步地完成它的工作。这就是我所拥有的,但似乎.doWork()从未启动,因为当我调用getDao.deleteAll()时,存储的函数没有运行 @Transactional public void delete() { final Session session = (Session) entityManager.getDelegate(); ExecutorService executorService

我有一个方法将调用一个存储函数。我希望它异步地完成它的工作。这就是我所拥有的,但似乎.doWork()从未启动,因为当我调用
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
。(交易是孤立的)