winform/mysql/长链接还是spool
(原文链接 http://ddbiz.com/?p=176)
今日写一段代码,要经常不定时的插入数据到数据库,但是总是有一段时间,比如5个小时或者10个小时或者更长的时间是没有数据插入的。
而在一段长时间的无数据操作后,再次插入数据到此链接,会发生诸如: 此链接无法写入数据等的错误,原来的代码大致如下:
class DHelper
{
private static IDbConnection writeCnn = new MySqlConnection();
public DHelper(string cnn)
{
writeCnn.ConnectionString = cnn;
writeCnn.Open();
}
public void DoInsert()
{
if (writeCnn.State == ConnectionState.Closed) writeCnn.Open();
using(IDbCommand cmd = writeCnn.CreateCommand())
{
cmd.CommandText = "insert into temptable values ...";
IDbDataParameter p = cmd.CreateParameter();
...
using(IDbTransaction tx = writeCnn.BeginTransaction())
{
try{
cmd.ExecuteNonQuery();
tx.Commit();
}catch{
tx.Rollback();
}
}
}
...
}
}
有时候错误会发生在 begintransaction 或者 ExecuteNonQuery() 上。
可能某些原因造成了链接的中断:
1.
2. 网络原因?
两种方法可以改进这个机制
1. 每次建立新链接,执行完毕后关闭链接
public void DoInsert()
{
using(IDbConnection writeCnn = new MySqlConnection(connectionStr))
{
using(IDbCommand cmd = writeCnn.CreateCommand())
{
cmd.CommandText = "insert into temptable values ...";
IDbDataParameter p = cmd.CreateParameter();
...
using(IDbTransaction tx = writeCnn.BeginTransaction())
{
try{
cmd.ExecuteNonQuery();
tx.Commit();
}catch{
tx.Rollback();
}
}
}
}
...
}
2. 每次执行前检查链接
public void DoInsert()
{
if (writeCnn.State == ConnectionStat.Closed) writeCnn.Open();
else if (writeCnn.State == ConnectionState.Broken){
writeCnn.Close(); writeCnn.Open();
}
using(IDbCommand cmd = writeCnn.CreateCommand())
{
cmd.CommandText = "insert into temptable values ...";
IDbDataParameter p = cmd.CreateParameter();
...
using(IDbTransaction tx = writeCnn.BeginTransaction())
{
try{
cmd.ExecuteNonQuery();
tx.Commit();
}catch{
tx.Rollback();
}
}
}
...
}
.net 应该对 connection spool 有发挥作用的,方式1应该和方式2在执行情况下没有太大的差别。那么实际的情况如何呢?下面的测试是在连续插入500条记录的情况下得出的统计数据,因为方式2的触发条件不存在(时间相对比较段/网络状况稳定),因此方式2的测试结果不能代表其实际的运行环境的状况。
<!--<! #t {margin:5px;padding:5px;}-->-->
插入次数 | 总用时 (ms) | 最大用时 (ms) | 最小用时 (ms) | 平均用时 (ms) | 超过60ms次数 | |
方式1 | 500 | 16140.625 | 156.25 | 15.625 | 32.28125 | 25 |
方式2 | 500 | 15390.625 | 187.5 | 15.625 | 30.78125 | 32 |
看来使用方式1基本上对一个频繁的写操作没有什么太大的影响。
方式2的实际环境测试,我在获得数据后再补入此处。