我正在测试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));
答案 0 :(得分:2)
到目前为止,这不是最好的解决方案,但我正在测试它是如何处理我的特定情况(目前在版本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;
}
}