重试调用数据库的方法
本文关键字:方法 数据库 调用 重试 | 更新日期: 2023-09-27 18:18:21
我正在制作一个应该24/7运行的系统,用计时器来控制它。有许多对数据库的调用,并且在某些时候,有两个方法试图打开连接,其中一个将失败。我已经尝试了一个重试方法,所以我的方法会成功。在Michael S. Scherotter和Steven Sudit的方法的帮助下,在没有goto的情况下更好地编写重试逻辑,我的方法看起来像这样吗:
int MaxRetries = 3;
Product pro = new Product();
SqlConnection myCon = DBcon.getInstance().conn();
string barcod = barcode;
string query = string.Format("SELECT * FROM Product WHERE Barcode = @barcode");
for (int tries = MaxRetries; tries >= 0; tries--) //<-- 'tries' at the end, are unreachable?.
{
try
{
myCon.Open();
SqlCommand com = new SqlCommand(query, myCon);
com.Parameters.AddWithValue("@barcode", barcode);
SqlDataReader dr = com.ExecuteReader();
if (dr.Read())
{
pro.Barcode = dr.GetString(0);
pro.Name = dr.GetString(1);
}
break;
}
catch (Exception ex)
{
if (tries == 0)
Console.WriteLine("Exception: "+ex);
throw;
}
}
myCon.Close();
return pro;
运行代码时,程序在"for(.....)"处停止,并出现异常:连接未关闭。连接的当前状态是打开的…这个问题就是我为什么要尝试这个方法的原因!如果有人知道如何解决这个问题,请写信。由于
你可以
myCon.Open();
在for循环中,但是
myCon = DBcon.getInstance().conn();
在它外面。通过这种方式,您可以多次打开同一个连接。如果你想防止DB连接丢失,你需要把它们都放在循环中
您应该将调用移到for语句之外的myCon.Open
或包装myCon.Open()在重新打开连接之前检查连接状态:
if (myCon.State != ConnectionState.Open)
{
myCon.Open();
}
编辑新信息
如何使用事务来保持数据完整性,获得多访问的动态连接,并将它们包装在using语句中以确保连接关闭?如
Using (SqlConnection myCon = new SqlConnection('ConnectionString'))
{
myCon.Open();
var transaction = myCon.BeginTransaction();
try
{
// ... do some DB stuff - build your command with SqlCommand but use your transaction and your connection
var sqlCommand = new SqlCommand(CommandString, myCon, transaction);
sqlCommand.Parameters.Add(new Parameter()); // Build up your params
sqlCommand.ExecuteNonReader(); // Or whatever type of execution is best
transaction.Commit(); // Yayy!
}
catch (Exception ex)
{
transaction.RollBack(); // D'oh!
// ... Some logging
}
myCon.Close();
}
这样,即使您忘记关闭连接,当连接到达Using语句的末尾时,它仍然会隐式地完成。
是否尝试添加
myCon.Close();
放到Finally块中。如果你有一个异常,它看起来永远不会被击中。我强烈建议您在Using语句中包装连接、命令对象等。这将确保它们被正确地处理并关闭连接。