如何确保从同一线程调用的方法使用相同的数据库会话

时间:2010-01-06 18:48:05

标签: java hibernate spring

在我们的系统中,我们有多线程处理引擎。在处理期间,每个线程调用方法以从数据库中检索数据。我们确定,如果从同一个线程调用的方法使用相同的数据库会话(会话来自池中),性能会大大提高。

Spring中是否有任何标准方法可以确保这样的事情,或者我们必须提出自己的自定义解决方案?

更新:忘记提及可以在不同的上下文中调用相同的方法,它们应该使用从池中获取会话的标准方法

4 个答案:

答案 0 :(得分:2)

Spring有一个名为TransactionSynchronizationManager的类。它将当前Session存储在ThreadLocal中。建议不要将TransactionSynchronizationManager用于开发人员,但您可以尝试使用它。

Session session = ((SessionHolder) 
   TransactionSynchronizationManager.getResource(sessionFactory)).getSession();

(如果您使用的是EntityManager,只需将“Session”替换为“EntityManager”)。

您可以在bean中注入sessionFactory - 它是每个应用程序。

查看this讨论。

我认为其他选项比手动线程处理更可取:

答案 1 :(得分:2)

我没有在你的问题中看到Spring。所以我假设您需要一个简单的实用程序来执行此操作。

class SessionUtil {
    private ThreadLocal currentSession;

    public Session getCurrentSession() {
        if(currentSession.get() == null) {
             Session s = //create new session
             currentSession.set(s);
        }
        return (Session)currentSession.get();
    }
}

Thread local将确保在同一个线程中它始终是同一个会话。如果您使用的是Spring,那么上面提到的类/实用程序(在其他响应中)应该是完美的。

答案 2 :(得分:0)

Spring 3.0有一个线程范围bean的概念(hovewer,默认情况下未注册此范围,请参阅文档):3.5 Bean scopes3.5.5.2 Using a custom scope

修改: 我说的是这个:

  

线程范围的bean 从Spring 3.0开始,   线程范围可用,但是   没有默认注册。更多   信息,请参阅文档   SimpleThreadScope。对于   关于如何注册这个的说明   或任何其他自定义范围,请参阅   Section 3.5.5.2, “Using a custom scope”

答案 3 :(得分:0)

Spring通过它Transaction Framework协调数据库会话,连接和线程(实际上,使用其TransactionSynchronizationManager - 请参阅说明here - 但您确实没有我想直接搞砸,这太可怕了。如果你需要协调你的线程,那么这是迄今为止最简单的方法。

但是,如何选择使用框架是最重要的。