DBの仕事を始めたばかりなので、基本的な質問に対する忍耐に感謝してください。ローカルマシンでSQL Server 2014を実行しています。小さなテーブルと、さまざまなアプローチをテストするための基本的なクライアントアプリケーションがあります。INSERT INTO
and UPDATE
ステートメントの両方でテーブルロックのように見えるものを取得しています。クライアントは、次のコードを持つASP.NETアプリケーションです。
OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn;
cmd.ExecuteNonQuery();
Console.WriteLine("updated row");
Thread.Sleep(15000);
tn.Rollback();
cn.Close();
このコードを実行してから、実行する管理スタジオからSELECT * FROM LAYOUTSv2
。クライアントスレッドが一時停止する両方の場合(つまり、コミット/ロールバックの前)、コミット/ロールバックが発生するまでSELECTクエリがハングします。
このテーブルには、主キーとして割り当てられたLAYOUTS_keyフィールドがあります。プロパティウィンドウでは、ページロックと行ロックの両方が許可された、一意でクラスター化されていることが表示されます。テーブルのロックエスカレーション設定は無効です...テーブルとAUTOの他の利用可能な設定を変更せずに試しました。私は試しましSELECT ... WITH (NOLOCK)
たが、すぐに結果を返しますが、ここや他の場所で十分に注意されているように、私がすべきことではありません。and ステートメントのROWLOCK
両方にヒントを付けてみましたが、何も変わっていません。 INSERT
UPDATE
私が探している動作はこれです:のコミットの前にINSERT
、他のスレッドからのクエリはINSERT
編集されている行を除くすべての行を読み取ります。UPDATE
他のスレッドからのクエリのコミットの前に、UPDATE
ed されている行の開始バージョンを読み取ります。これを行う方法はありますか?ユースケースを明確にするために他の情報を提供する必要がある場合は、お知らせください。ありがとう。
newkey
が「something';DELETE FROM LAYOUTSv2 --
」に設定した場合を想像してください。ユーザーがアポストロフィを挿入してクエリを操作したため、更新は正常に完了し、テーブルが空になります。通常、パラメーター化されたクエリはのようなものになります。その後、コード内の(パラメーター)にUDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?
値を個別に割り当てます?
。
WHERE LAYOUTS_key='" + newkey + "'
SQLインジェクションを含むさまざまな理由により、完全なno-noは、パラメーター化されたクエリを使用する必要があります。