我们有两个直接相关的问题,可以简化为一段非常简单的代码。 假设机器1托管应用程序,机器2托管数据库,通过集线器通过以太网连接。 我们将通过从集线器拔下网络电缆来模拟网络问题。SqlServer由于网络丢失而造成楔形连接
你可能会说“让你的网络可靠”。我也是如此。我需要证明这并非首先在客户相信之前明确地捕捉到问题。
我们无法用超时解决这个问题,因为我们有一些/非常/长时间运行的查询和非查询。是的,他们中的一些人确实需要一个小时或更长时间,并且用户不会忍受长时间的冻结会话以获得真正的错误。他们杀了它。
using System.Data;
using System.Data.SqlClient;
public class test {
public static void hang1()
{
using SqlConnection oConnection = applib.getConnection() // returns an open connectin
{
using SqlCommand oCmd = new SqlCommand("WAITFOR DELAY 00:01:00", oConnection)
oCmd.ExecuteNonQuery(); // unplug cable between hub and database server when in this call and this call never returns
}
}
public static void hang2()
{
using SqlCommand oTCmd = new SqlCommand("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE", oConnection)
oCmd.ExecuteNonQuery();
using oTransaction = new SqlClient.SqlTransaction
{
using SqlCommand oCmd = new SqlCommand("SELECT max(id) FORM Table1")
{
oCmd.Transaction = oTransaction;
oCmd.ExecuteScaler();
System.Threading.Thread.Sleep(60 * 1000);
// Disconnect the cable between the hub and the application server here
// Now table Table1 is locked and will remain locked until the transaction
// is manually killed from the database server.
oCmd.ExecuteScaler();
}
}
}
}
我们正在寻求一种解决方案来检测事务卡住而不必设置超时。如果我正在设计我自己的TCP/IP协议,我会设计一个心跳进入它,以便没有足够秒数的响应=结束死亡,纾困,清理。我想要一种方法来实现相同的想法,那就是将安静的挂起变成嘈杂的崩溃,以便清理代码可以清理它。
那么这就是最好的答案。现在,如何在客户端连接上设置Keepalive将完成它。 – Joshua 2013-05-02 23:34:47
@Joshua,事实证明,它只能由服务器发送,而不是客户端发送。 – Ben 2013-05-03 09:09:56
我接受这个答案是答案的一半,另一半不存在,任何使它存在的方式都会涉及很多骇客。 – Joshua 2013-05-04 22:13:18