我有一个简单的SQL语句,我想在很短的时间内调用几次(大约400次调用< 10秒)。达到大约200次调用后,我收到以下SQL错误:
System.InvalidOperationException:'超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池化连接都在使用中并且达到了最大池大小。'
我已经阅读了很多关于此错误的帖子。他们都建议使用using
块包装代码,或者最后调用SQL连接的.Close()
方法。我已经实现了两者,它仍然无法正常工作。我没有正确实现它吗? (该方法在没有重复调用时工作正常。)
我的代码如下所示:
public static ObjectModel GetObject(int objGroupId, DateTime date)
{
ObjectModel obj = new ObjectModel () { EffectiveFrom = date };
// Get connection string from the App.Config file
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("[dbo].[GetObjectData]", connection))
{
// Request the data which were in force on the specified date
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@Date", SqlDbType.DateTime).Value = obj.EffectiveFrom;
command.Parameters.Add("@ObjecGrouptId", SqlDbType.Int).Value = objGroupId;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int objId = reader.GetInt32NullIsZero("Id");
decimal value = reader.GetDecimalNullIsZero("value");
SetObjData(obj, objId, value);
}
}
}
connection.Close();
}
return obj;
}
答案 0 :(得分:2)
您显示的代码看起来干净;所有正确的using
等都在那里。这让我怀疑在之外的东西这个代码正在保持连接并占用池。我所知道的唯一这样的功能是:环境交易,即TransactionScope
。
作为一个调试工具只是为了测试这个假设,我建议尝试抑制一个TransactionScope
(如果有的话),你可以通过:
using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
//... the rest of your code
connection.Close();
}
tran.Complete();
}
请注意,Open
的创建和connection
必须在内部在被抑制的区域内进行计数。
如果这导致问题消失,那么:环境事务导致所有连接在更广泛的事务中被登记 - 可能是DTC事务(因为LTM事务可以重新使用连接,IIRC)。
所以:如果这个修复它,那么坦率地说我的建议是改变方法,允许你选择性地将连接作为输入传递,允许你重用400的单个连接操作而不是依靠连接池。
重要提示:抑制交易通常不是一个好主意;那次交易是有原因的。这里的代码只是一个诊断辅助工具,用于调查这是否是问题。
答案 1 :(得分:1)
问题解决了。事实证明,有一种(完全不同的方法)是$alloptions = array(1 => 'Option A', 2 => 'Option B');
if(isset($_POST['select'])){
if(!array_key_exists($_POST['select'], $alloptions)){
echo 'error';
}
}
foreach($alloptions as $optionid => $optionname){
echo '<option value="'.$optionid.'">'.$optionname.'</option>;
}
。我将其更改为async
(而不是Task
)并添加了void
。所以@JeroenMostert走在了正确的轨道上。我仍然不明白为什么异常总是发生在与await
部分无关的方法中。