3

これは、 SQL Server で行レベルのロックを強制することは可能ですか?の拡張です。. ユースケースはこちら

口座番号、残高などを含む口座テーブルがあります。このテーブルは多くのアプリケーションで使用されています。私がアカウントを変更している間に、他の誰かが別のアカウントを変更している可能性は十分にあります。したがって、予想される動作は、私が自分のアカウント (ROW) をロックし、他のユーザーが彼 (別の ROW) をロックすることです。

しかし、SQL Server 2008 R2 はこのロックをページ/テーブルにエスカレートし、2 番目のユーザーはタイムアウト例外を取得します。参照されている質問に記載されているすべての解決策を試しましたが、何も機能していません。

SQL Server に行レベルのロックのみを強制的にロックさせるにはどうすればよいですか、またはページ/テーブルのロックで機能するようにこのモデルを変更するにはどうすればよいですか?

EDIT 更新はPKを介して単一のレコードを対象としており、インデックスが作成されているため、1行のみが更新/ロックされており、プロセスには1分以上かかりません

編集 今、何か奇妙なことが起こっているようです。複数の接続を開いている DAL 用の ORM ライブラリを使用しており、サポートに質問しました。しかし、テスト目的で、クエリツールで2つのセッションを開き、次のことを行いました

Session # 1
begin tran
UPDATE myTable SET COL_1 = COL_1 WHERE COL_1 = 101;

Session # 2
SELECT COL_1 FROM myTable WHERE COL_1 = 101;

セッション # 2 のクエリがタイムアウトしました!!! の他の値のクエリは正常に機能しCOL_1ています。同じレコードが別のセッションで編集モードになっている場合、セッションの SELECT がブロックされているように見えます。

Oracle は、他のセッションによって変更されている間、行の選択をサポートしていますが (デフォルトのパラメーター/キーワードなし)、SQL Server はサポートしていません (デフォルトのパラメーター付き/キーワードなし)。そのため、問題はライブラリにあるようです。

4

2 に答える 2

9

SQL Server は常にデフォルトで行レベルのロックを使用します。

一定量 (約 5000 行) を超える行をロックすると、SQL Server はロック エスカレーション(5000 行を超える行を個別にロックする代わりにテーブルをロックする) を実行して、パフォーマンスを最適化し、リソースの使用を最適化しますが、これは良いことです! :-)

これを完全にオフにする方法はありますが、お勧めしません! SQL Server のストレージ エンジン内の非常に基本的なメカニズムをいじっているためです。

見る:

于 2012-05-18T07:30:46.407 に答える
2

あなたのシステムを、クライアントとサーバーが非常に遅い回線 (例: カタツムリ メール) で接続され、ユーザーが非常に長い時間 (例: 1 週間) レコードを変更しているクライアント サーバー アプリケーションとして想像してみてください。次に、行/データをロックする必要があるとき、および実際に行/データの変更を許可するときなどについて考えてみてください.SQLサーバーの内部ロックを数日間配置することは、もはや良い考えではないようです.

状況がない場合、2 人のユーザーが同じレコードを変更する必要がある場合、データを変更する際にロックする必要はまったくありません。データベースでレコードが変更されたとき、つまりユーザーが変更をコミットしている間だけ、ロックする必要があります。(これは楽観的ロックのシナリオです。) もちろん、2 人のユーザーが同じデータを変更すると、最新の変更によって以前の変更が上書きされます。

2 人のユーザーが同じデータを変更してはならない (悲観的ロック) ことが絶対に必要な場合、おそらく最も一般的な方法は、アプリケーション定義のロック テーブルまたはデータ テーブル内の特定のフィールドを使用することです。1 人のユーザーがレコードをチェックアウトするとき (編集を開始するときなど)、そのレコードが既に使用されている (ロックされている) かどうかを確認し、使用されていない場合は、このレコードをロック済みとしてマークする必要があります。もちろん、古いロックを削除するにはいくつかの機能が必要です。

または、そのような場合には SQL サーバーの内部固有の関数を使用します。ここを見てください: MSDN の sp_getapplock 関数; このようにして、レコードが永久にロックされたままになるなどの心配をする必要はありません。

于 2012-05-18T08:05:17.547 に答える