在Hibernate / C3P0中处理连接池耗尽并避免死锁

时间:2016-11-12 10:13:59

标签: java multithreading hibernate dining-philosopher

我的旧应用程序跟随链查询我的数据库:Spring Tx -> Hibernate -> C3P0。现在我需要基于现有架构实现新功能。

我通常使用@Transactional注释或手动调用PlatformTransactionManager来输入事务上下文。

有时,为了执行异步和大数据操作,我使用SessionFactory API打开无状态会话。我们的线程池控制良好,我们从未遇到任何其他问题

我第一次要求并行执行多个数据库操作以提高性能。我对它有疑问,因为我对多线程操作非常小心。

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

多线程课教导学生为了防止僵局(吃哲学家问题),应以交易方式获取资源:一旦你获得了一个分支,如果你不能在合理的时间内获得第二个,那就释放第一个然后再试一次。

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

据我所知,SessionFactory API正在阻止,并且不允许设置监视程序

1 个答案:

答案 0 :(得分:0)

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

通常,在Java世界中,如果API不提供用于获取资源的监视程序方法,您可以将其委派给Futureget(int timeout, TimeUnit timeUnit)提供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 } API来约束执行。< / p>

步骤1:资源获取的监视计时器

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

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;
    }
}

第2步:按照哲学家的方式进食

正如我所说,我的问题看起来基本上就像餐饮哲学家,除了我们不只是有两把叉子,而是勺子和刀子总共需要4把。

MAX_ATTEMPTS

如果你超越#guitar { border : 5px solid; padding : 10px; margin-bottom : 2%; overflow: auto; /* <--- this rule does the trick */ } 会发生什么事情取决于你,开发人员!