一部の開発者/データベース管理者は、読み取り専用の呼び出しであっても、すべてのデータベース呼び出しでトランザクションを使用することを推奨していると読んでいます。トランザクション内で挿入/更新することは理解していますが、トランザクション内で読み取る利点は何ですか?
7 に答える
したがって、データベースの一貫したビューが得られます。互いにリンクしている 2 つのテーブルがあり、何らかの理由で 2 つの選択を行うと想像してください...疑似コードで:
myRows = query(SELECT * FROM A)
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id])
2 つのクエリの間で、誰かが B を変更していくつかの行を削除すると、問題が発生します。
RoBorg が言ったことと同様に、SELECTS w/i トランザクションを実行して、ステートメント間のファントム データの読み取りを防止します。ただし、SQL Server の既定のトランザクション分離レベルは READ COMMITTEDであり、ダーティ リードのみを防止することに注意してください。ファントムデータを防ぐには、少なくとも REPEATABLE READ を使用する必要があります。「このオプションは必要な場合にのみ使用してください。」
これはもっと知っておくべきことなので、ここ数分間チェックしてきました。これが私が見つけたものです。
人がレコードを読んでいる間にその行をロックし、それを変更したり読んだりしたくない場合は、選択の周りでトランザクションが役立ちます。たとえば、次のクエリを実行します。
(クエリ ウィンドウ 1 内)
BEGIN TRAN SELECT * FROM MYTABLE WITH (ROWLOCK XLOCK) WHERE ID = 1
(クエリ ウィンドウ 2)
SELECT * FROM MYTABLE WHERE ID = 1
(クエリ ウィンドウ 2 は、ウィンドウ 1 でこれを実行するまで結果を返しません)
コミットトラン
便利なリンク:
http://msdn.microsoft.com/en-us/library/aa213039.aspx
http://msdn.microsoft.com/en-us/library/aa213026.aspx
http://msdn.microsoft.com/en-us/library/ms190345.aspx
私の目標は、何かをブロックすることでした-そして、そこにXLOCKを追加した後、最終的に機能しました。ROWLOCK を使用するだけでは機能しませんでした。私はそれが共有ロックを発行していたと仮定しています(そしてデータは読み取られました)..しかし、私はまだこれを調査しています。
- WITH (UPDLOCK ROWLOCK) - を追加すると、行を選択してロックして更新できるようになり、同時実行性が向上します。
テーブル ヒントには注意してください。それらを無計画に適用し始めると、アプリのユーザー数が少なくても、システムの速度が低下します。これは、これを調べる前に私が知っていたことの1つです;)
トランザクションの主な目的の 1 つは、問題が発生した場合にロールバックの可能性を提供することです。
「トランザクション」の動作は、SQL サーバーによって大きく異なることがわかりました。場合によっては、トランザクションを開始すると、トランザクションがコミットまたはロールバックされるまで、他のすべての接続がロックされて SQL を実行できなくなります (MS SQLServer 6.5)。他のものには問題はなく、変更がある場合にのみロックされます (オラクル)。ロックは、セル ロック/行ロック/ページ ロック/テーブル ロックなど、変更のみを含むように拡張することもできます。
通常、複数の挿入/削除/更新ステートメント間のデータ整合性を維持する必要がある場合にのみ、トランザクションを使用します。それでも、データベースが自動的かつアトミックに実行できるように、DB 定義のカスケード削除を使用してこれを実装することを好みます。
複数の変更をロールバックしたい状況が予測できる場合はトランザクションを使用しますが、それ以外の場合、データベースはそれを処理するための追加のコードなしでアトミックな更新を行います。