NServiceBusを使用してシステムを構築しており、DataLayerはLinq2SQLを使用しています。
システムは2つのサービスで構成されています。
Service1はNSBからメッセージを受信します。データベース内のTable1にクエリを実行し、Table1にレコードを挿入します。特定の条件が満たされると、新しいNSBメッセージが2番目のサービスに送信されます。
Service2は、Service1からメッセージを受信し、データベースに関連しないその他の作業を行うときに、Table1のレコードも更新します。Service2は長時間実行されるプロセスです。
私が抱えている問題は、Service2がTable1のレコードを更新した瞬間、テーブルがロックされていることです。Service2が処理をすべて完了するまで、ロックは有効になっているようです。つまり、データコンテキストが破棄された後、ロックが解放されません。
これにより、Service1のクエリがタイムアウトします。Service2が処理を完了すると、Service1は問題なく処理を再開します。
したがって、たとえばService1コードは次のようになります。
int x =0;
using (DataContext db = new DataContext())
{
x = (from dp in db.Table1 select dp).Count(); // this line will timeout while service2 is processing
Table1 t = new Table1();
t.Data = "test";
db.Table1.InsertOnSubmit(t);
db.SubmitChanges();
}
if(x % 50 == 0)
CallService2();
service2のコードは次のようになります。
using (DataContext db = new DataContext())
{
Table1 t = db.Table1.Where(t => t.id == myId);
t.Data = "updated";
db.SubmitChanges();
}
// I would have expected the lock to have been released at this point, but this is not the case.
DoSomeLongRunningTasks();
// lock will be released once service2 exits
DatacontextがService2に配置されているときに、ロックが解放されない理由がわかりません。
私が呼んでいる問題を回避するために:
db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
これは機能しますが、私はそれを使用することに満足していません。この問題をきちんと解決したい。
誰かが以前にこの種の問題を経験したことがあり、誰かがそれを解決する方法を知っていますか?データコンテキストが破棄された後、ロックが解放されないのはなぜですか?
前もって感謝します。
非常に長い投稿でごめんなさい。
編集:
配送などの現実の状況でこれを見ると、次のようになります。
service1は、クレートレコードをデータベースに追加します。特定の数またはクレートレコードが存在する場合、クレートはコンテナレコードに追加されます(コンテナレコードが存在しない場合は作成されます)。次に、出荷レコードを作成し、すべてのコンテナを閉じて、出荷レコードに割り当てます。
次に、service2を呼び出して出荷記録を処理します。service2への呼び出しはBus.Send呼び出しですが、サガの一部である可能性があります。service2は、割り当てられている船の各クレートレコードを更新します。その後、他のいくつかの出荷指示が処理されます。service2が処理している間、次の出荷のためにさらに多くのクレートを受け取ることができますが、現状では、service2が出荷の処理を完了するまで、それらをコンテナに割り当てることはできません。