繁体   English   中英

ServiceStack:检测IDbConnection是否“忙” - DataReader是否已打开(尝试实现“连接池”)

[英]ServiceStack: Detect if IDbConnection is “busy” - is a DataReader is open (trying to implement a “connection pool”)

我正在测试ServiceStacks OrmLite。 我已经普遍使用没有OrmLite的MySql,现在我遇到了此错误消息中最简单描述的问题:

已经有一个与此Connection关联的开放DataReader,必须先关闭它。

由于我有一个多线程应用程序,某些线程将轮询数据库,而其他线程将在需要时插入,更新或选择“按需”。 这导致上述异常。

我需要做的是能够检测连接(IDbHandler)是否“忙”; 有一个开放的DataReader或其他东西。 如果它正忙,请进行下一个连接(从我想要实现的“连接池”)。 问题是,我没有可以在IDbHandler对象中使用的方法或属性来确定它是否繁忙。

我已经在“正常”的mysql情况下通过简单地使用我发送MySqlCommand或只是查询字符串的方法解决了这个问题,例如:

dbConnections.ExecuteQuery("SELECT * FROM test");
dbConnections.ExecuteQuery(cmd); // cmd == MySqlCommand

并且ExecuteQuery将处理找到一个打开的连接,并在那里传递cmd /查询。

但是,由于我使用OrmLite,它有很多IDbConnection的扩展方法,我不想为每个方法创建“代理方法”。 在上面简单的mysql案例中,实际上只需要一个方法,它需要一个MySqlCommand,但OrmLite中的许多方法都不是这样。

第一个问题:

  • 如何检测连接是否繁忙? 我想避免尝试捕获情况来检测它。

第二个问题:

  • 有没有办法传递整个“方法”调用,如:

例:

dbConnections.Run(iDbHandler.Select<MyObject>(q => q.Id > 10));
// or
dbConnections.Run(iDbHandler.Where<MyObject>(q => q.Id > 10));
// or
dbConnections.Run(iDbHandler.SomeOtherWeirdMetod<MyObject>(q => bla bla bla));

到目前为止,这不是最好的解决方案,但它是我正在测试的方法,以查看它如何处理我的特定情况(目前在版本3.97)。 和Ted一样,我看到开放式数据读取器经常例外,或者连接被关闭返回。

在我的使用中,所有服务都继承我的父服务(后者继承服务)来处理一些常见的元数据处理。 我选择让我的基本服务覆盖服务的Db属性,并快速检查Db连接的状态并尝试恢复。 立即修复的一个案例如下:

我的MsSql服务器正在故障转移群集中运行。 当SQL服务器从节点A翻转到节点B时,我没有在ServiceStack中找到内置机制来检测其内存连接是否“脏”并需要重新连接。

欢迎提出意见和改进。

public override System.Data.IDbConnection Db
{
    get
    {
        try
        {
            var d = base.Db;
            if (d == null || d.State != System.Data.ConnectionState.Open)
                return  ForceNewDbConn();
            else
                return d;
        }
        catch (Exception ex)
        {
            return ForceNewDbConn();
            //throw;
        }
    }
}

private IDbConnection ForceNewDbConn()
{
    try
    {
        var f = TryResolve<IDbConnectionFactory>();
        if (f as OrmLiteConnectionFactory != null)
        {
            var fac = f as OrmLiteConnectionFactory;
            fac.AutoDisposeConnection = true;
            var newDBconn = fac.Open();
            return newDBconn;
        }
        return base.Db;
    }
    catch (Exception ex)
    {
        throw;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM