注:
当问题没有正确处理读卡器/连接,或者错误是由于处理不当的延迟加载时,我已经回答了数百万个问题。我认为这个问题是另一个问题,可能与MySQL的.NET连接器有关。
我通过其.NET连接器(6.8.3)广泛使用MySQL服务器(5.6)数据库。出于性能原因,所有表都使用MyISAM引擎创建。我只有
一个过程
具有
一个线程
(
更新:
事实上,这不是真的,请参见下文)顺序访问数据库,因此不需要事务和并发。
今天,经过几个小时的处理后,出现了以下代码:
public IEnumerable<VectorTransition> FindWithSourceVector(double[] sourceVector)
{
var sqlConnection = this.connectionPool.Take();
this.selectWithSourceVectorCommand.Connection = sqlConnection;
this.selectWithSourceVectorCommand.Parameters["@epsilon"].Value
= this.epsilonEstimator.Epsilon.Min() / 10;
for (int d = 0; d < this.dimensionality; ++d)
{
this.selectWithSourceVectorCommand.Parameters["@source_" + d.ToString()]
.Value = sourceVector[d];
}
using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
{
while (reader.Read())
{
yield return ReaderToVectorTransition(reader);
}
}
this.connectionPool.Putback(sqlConnection);
}
引发了以下异常:
MySqlException:已存在与此连接关联的打开的DataReader,必须首先关闭该连接。
以下是堆栈跟踪的相关部分:
位于MySql.Data.MySqlClient.ExceptionInterceptor.Row(异常异常)
位于MySql.Data.MySqlClient.MySqlConnection.Row(异常ex)
位于MySql.Data.MySqlClient.MySqlCommand.CheckState()
位于MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior行为)
位于MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
在C:\Users\bartoszp中实现.VectorTransitionsMySqlTable.d_27.MoveNext()。。。\implementation\VectorTransitionsMySqlTable.cs:line 201
位于System.Linq.Enumerable.d_3a
1.MoveNext()
at System.Linq.Buffer
1..ctor(IEnumerable
1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1个来源)
在实现时。VectorTransitionService.Add(VectorTransition VectorTransition)在C:\Users\bartoszp中。。。\implementation\VectorTransitionService.cs:line 38
在程序中。转到[T](环境`2 p,Space parentSpace,EpsilonEstimator epssilonEstuator,ThresholdEstimator thresholdEstimater,TransitionTransformer TransitionTransformer,AmbiguityCalculator ac,VectorTransitionTableFactory vttf,AxesTableFactory atf,NeighbourhoodsTableFactory ntf,AmbigiguitySamplesTableFactory astf,AmbinguitySampleMatchesTableFactory asmtf,MySqlConnectionPool connectionPool,Boolean rejectDu在C:\Users\bartoszp中,重复项、布尔addNew)。。。\程序.cs:line 323
这个
connectionPool.Take
返回满足以下谓词的第一个连接:
private bool IsAvailable(MySqlConnection connection)
{
var result = false;
try
{
if (connection != null
&& connection.State == System.Data.ConnectionState.Open)
{
result = connection.Ping();
}
}
catch (Exception e)
{
Console.WriteLine("Ping exception: " + e.Message);
}
return result && connection.State == System.Data.ConnectionState.Open;
}
(这与我之前的问题有关,当时我解决了一个不同但相似的问题:
MySQL fatal error during information_schema query (software caused connection abort)
)
这个
FindWithSourceVector
方法由以下代码段调用:
var existing
= this.vectorTransitionsTable
.FindWithSourceVector(vectorTransition.SourceVector)
.Take(2)
.ToArray();
(我最多需要找到两个重复的向量)-这是
VectorTransitionService.cs:line 38
堆栈跟踪的一部分。
现在最有趣的部分是:当调试器在异常发生后停止执行时,我已经研究了
sqlConnection
要查找的对象,即
它没有关联的读取器
(下图)!
为什么会发生这种情况(显然是“随机”的——在过去的~20小时里,几乎每分钟都会调用这种方法)?我能避免这种情况吗
Ping
抛出异常并祈祷它会有所帮助)?
有关连接池实施的其他信息:
Get
用于只调用简单查询而不使用读取器的方法,因此可以以可重入方式使用返回的连接。本例中未直接使用(因为涉及读者):
public MySqlConnection Get()
{
var result = this.connections.FirstOrDefault(IsAvailable);
if (result == null)
{
Reconnect();
result = this.connections.FirstOrDefault(IsAvailable);
}
return result;
}
这个
Reconnect
方法只是遍历整个数组并重新创建和打开连接。
Take
使用
收到
但也会从可用连接列表中删除返回的连接,因此如果某些方法在使用读取器期间调用其他也需要连接的方法,则不会共享该连接。这里也不是这样,因为
FindSourceVector
方法很简单(不调用使用DB的其他方法)。然而
拿
用于惯例-如果有读者,请使用
拿
:
public MySqlConnection Take()
{
var result = this.Get();
var index = Array.IndexOf(this.connections, result);
this.connections[index] = null;
return result;
}
Putback
只需将连接放置到第一个空点,或者在连接池已满时忘记它:
public void Putback(MySqlConnection mySqlConnection)
{
int index = Array.IndexOf(this.connections, null);
if (index >= 0)
{
this.connections[index] = mySqlConnection;
}
else if (mySqlConnection != null)
{
mySqlConnection.Close();
mySqlConnection.Dispose();
}
}