SQL Server 2005でNHibernateを使用すると、次のシナリオが発生しました。
次の手順を含むビジネスプロセスがあります。
- トランザクションを開始します
- nhibernateマップオブジェクトを作成する
- nhibernateマップされたオブジェクトを保存します
- 他のビジネスワークフローステップを実行する
- ステップ2でnhibernateマップされたオブジェクトを更新します
- トランザクションをコミットする
シングルスレッド環境では、これは正常に機能します。ただし、別々のエンティティで同じユースケースを実行するマルチスレッド負荷テストを実行すると、いくつかのデッドロックが発生したことがわかりました。トランザクション分離レベルは、読み取りコミットのデフォルト設定のままにしました。
調査したところ、問題の原因は、nhibernateがステップ2で作成され、ステップ5で更新されたエンティティの挿入と更新ステートメントを発行することであることがわかりました。さらにテストすると、更新ステートメントがテーブル全体をロックしているのではなく、行だけが更新されると、別のスレッドが挿入または更新のためにテーブルにアクセスしようとすると、デッドロックが発生します。
Q1:nhibernateを取得して、更新している行をロックすることはできますか?つまり、更新を発行するときに行ロックを適用することはできますか?
まだ、挿入してから更新するステートメントではなく、単一の挿入ステートメントを実行するようにnhibernateを取得する方法を見つけていません。
Q2:この動作を変更するための構成オプションを知っている人はいますか?
SQL Serverデータベースでスナップショット分離をオンにし、トランザクション分離レベルをスナップショットに設定することで、マルチスレッド負荷テストで発生するデッドロックの問題を克服することができました。
誰かが同様の問題を経験したかどうか聞いてみたいです。