SessionFactory - 多个数据库的一个工厂

Posted

技术标签:

【中文标题】SessionFactory - 多个数据库的一个工厂【英文标题】:SessionFactory - one factory for multiple databases 【发布时间】:2011-04-05 21:06:06 【问题描述】:

我们有多个数据库具有相同架构,但每个数据库中的数据不同。我们正在创建一个会话工厂来处理这个问题。

问题是直到运行时我们才知道我们将连接到哪个数据库,什么时候我们可以提供它。但是在启动以获取工厂构建时,我们需要使用该模式连接到数据库。我们目前通过在已知位置创建架构并使用它来做到这一点,但我们想删除该要求。

在不指定连接的情况下,我无法找到创建会话工厂的方法。我们不希望能够使用没有参数的 OpenSession 方法,这没关系。

有什么想法吗? 谢谢 安迪

【问题讨论】:

为什么不在运行时在 Configuration 对象中提供连接详细信息,而不是在编译时在配置文件中提供? 你为什么这样做?我很好奇…… @Kent:我们做到了,问题是我们在构建工厂时(在启动时)我们实际上并不需要连接,而是构建它以便用户无需等待当他们到达真正打开连接的地步时。 @Pierre:可扩展性和正常运行时间。相同的数据最终会出现在多个地方,但是流量较高的客户可能会拥有自己的服务器,而流量较低的客户可以共享,而且一个系统出现故障并不会让所有人都崩溃。 如果您有一个具有复制功能的数据库集群,则不必有 2 个连接字符串。检查这个答案:***.com/questions/751634/… 【参考方案1】:

要么实现您自己的IConnectionProvider,要么将您自己的连接传递给ISessionFactory.OpenSession(IDbConnection)(但请阅读该方法中有关连接跟踪的cmets)

【讨论】:

愿意给我们举个例子吗? Mauricio,谢谢,我会检查一下。我曾考虑过您的后一个建议,但从我的研究中不清楚 NHibernate 是否会关闭连接或者我们是否会承担责任。我会阅读 IConnectionProvider,它看起来可能更接近我们的需要。【参考方案2】:

我们想出的解决方案是创建一个类来为我们管理它。该类可以利用方法调用中的一些信息做一些路由逻辑来判断数据库在哪里,然后通过连接字符串调用OpenSession。

【讨论】:

【参考方案3】:

您也可以为此使用来自 brady gaster 的出色 NuGet 包。我用他的 NHQS 包做了我自己的实现,效果很好。

你可以在这里找到它:

http://www.bradygaster.com/Tags/nhqs

祝你好运!

【讨论】:

【参考方案4】:

遇到了这个问题,我想我应该为未来的读者添加我的解决方案,这基本上是 Mauricio Scheffer 所建议的,它封装了 CS 的“切换”并提供单点管理(我更喜欢这个而不是必须传递到每个会话调用,少“错过”而出错)。

我在客户端身份验证期间获取连接字符串,然后在上下文中设置,然后使用以下 IConnectinProvider 实现,在打开会话时为 CS 设置该值:

/// <summary>
/// Provides ability to switch connection strings of an NHibernate Session Factory (use same factory for multiple, dynamically specified, database connections)
/// </summary>
public class DynamicDriverConnectionProvider : DriverConnectionProvider, IConnectionProvider

    protected override string ConnectionString
    
        get
        
            var cxnObj = IsWebContext ?
                HttpContext.Current.Items["RequestConnectionString"]: 
                System.Runtime.Remoting.Messaging.CallContext.GetData("RequestConnectionString");

            if (cxnObj != null)
                return cxnObj.ToString();
            //catch on app startup when there is not request connection string yet set
            return base.ConnectionString;
        
    

    private static bool IsWebContext
    
        get  return (HttpContext.Current != null); 
    

然后在 NHConfig 期间接线:

var configuration = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2005
                            .Provider<DynamicDriverConnectionProvider>() //Like so

【讨论】:

以上是关于SessionFactory - 多个数据库的一个工厂的主要内容,如果未能解决你的问题,请参考以下文章

我们可以为单个数据库连接进行多个并行事务吗? [复制]

SessionFactoryTransactionQuery

Hibernate中的session的线程安全问题

AbstractRoutingDataSource动态数据源切换

hibernate中SessionFactory与Session的作用

8 -- 深入使用Spring -- 8...2 管理Hibernate的SessionFactory