非常に単純なコードに縮小できる 2 つの直接関連する問題があります。マシン 1 がアプリケーションをホストし、マシン 2 がデータベースをホストし、ハブを介してイーサネットで接続されているとします。ハブからネットワーク ケーブルを抜いて、ネットワークの問題をシミュレートします。
おそらく「ネットワークの信頼性を高めてください」と言うでしょう。私もそうです。顧客が信じる前に、問題を明確に把握して、それが最初ではないことを証明する必要があります。
/非常に/長時間実行されるクエリと非クエリがあるため、この問題をタイムアウトで解決することはできません。はい、中には実際に 1 時間以上かかるものもあり、ユーザーは、実際のエラーが発生するのに十分な時間、フリーズしたセッションをじっと見つめることに我慢できません。彼らは代わりにそれを殺します。
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 プロトコルを設計する場合は、ハートビートを設計して、十分な時間応答がない場合 = 停止、救済、クリーンアップと結論付けるようにします。同じアイデアを実現する方法が欲しいです。つまり、静かなハングをノイズの多いクラッシュに変えて、クリーンアップ コードでクリーンアップできるようにすることです。