1

我的旧应用程序遵循链来查询我的数据库:Spring Tx -> Hibernate -> C3P0. 现在我需要在现有架构的基础上实现新功能。

我通常通过使用@Transactional注释或手动调用PlatformTransactionManager.

SessionFactory有时,为了执行异步和大数据操作,我使用API打开一个无状态会话。我们从来没有遇到任何额外的问题,因为我们的线程池得到了很好的控制

第一次,我的要求是并行执行多个数据库操作以加快性能。我对此表示怀疑,因为我对多线程操作非常小心。

对于数据库中的每个实体,我可以在单独的线程上执行对帐操作。但是每个协调操作对它产生的两个线程中的每一个都使用一对连接。所以每个线程基本上有4个连接。

多线程课告诉学生为了防止死锁(吃哲学家问题),资源的获取应该是事务性的:一旦你获得了一个fork,如果你不能在合理的时间内获得第二个,释放第一个重试.

我的问题很简单。给定SessionFactoryAPI,如果池已满,我如何编写不会无限期等待来自 c3p0 的 4 个连接的代码?我的意思StatelessSession是只有当有 4 个空间时我才需要 4 秒,否则我可以等待并重试。

据我所知,SessionFactoryAPI 是阻塞的,不允许设置看门狗

4

1 回答 1

0

目前的想法是使用普通的旧解决方法。

一般来说,在 Java 世界中,如果 API 不提供用于获取资源的看门狗方法,您可以将其委托给 a Future,后者提供get(int timeout, TimeUnit timeUnit)API 来约束执行。

第一步:资源获取看门狗定时器

所以基本上,我如何在超时范围内获得无状态会话?

private Future<StatelessSession> getStatelessSession(SessionFactory sessionFactory)
{
    return asyncTaskExecutor.submit(new Callable<StatelessSession>()
    {

        @Override
        public StatelessSession call() throws Exception
        {
            return sessionFactory.openStatelessSession();
        }
    });
}

try {
    StatelessSession session = getStatelessSession(sessionFactory).get(3000,TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    // go to step 2
}

第二步:像哲学家那样吃

正如我所说,我的问题看起来基本上像用餐哲学家,只是我们不仅有两个叉子,而且还有勺子和刀子,总共有 4 个。

StatelessSession session1, session2, session3, session4;
for (int i=0; i<MAX_ATTEMPTS;i++) {
    try {
        session1 = tryGetSessionOrBoooooom();
    } catch(TimeoutException ex) {
        continue;
    }
    try {
        session2 = tryGetSessionOrBoooooom();
    } catch(TimeoutException ex) {
        session1.close();
        continue;
    }
    try {
        session3 = tryGetSessionOrBoooooom();
    } catch(TimeoutException ex) {
        session2.close();
        session1.close();
        continue;
    }
    try {
        session4 = tryGetSessionOrBoooooom();
    } catch(TimeoutException ex) {
        session3.close();
        session2.close();
        session1.close();
        continue;
    }
}

如果你超越MAX_ATTEMPTS了会发生什么取决于你,开发者!

于 2016-11-12T10:46:09.737 回答