3

次のシナリオを想定しましょう。

[Start TX]
SELECT userName FROM users WHERE userId = 1; -- returns x
UPDATE users SET userName = 'y' where userId = 1;
SELECT userName FROM users WHERE userId = 1; -- returns y
[End TX]

データベースはどのようにして2回目にyを返すことを知っていますか?トランザクション状態はどのようにクエリ処理に統合されますか?

別のシナリオ:

[Start TX]
SELECT userName FROM users, accounts WHERE useres.userId = accounts.userId AND accounts.balance < 0; -- returns x
UPDATE accounts SET balance = 100 where userId = 1;
SELECT userName FROM users, accounts WHERE useres.userId = accounts.userId AND accounts.balance < 0; -- returns nothing
[End TX]

同じ質問-データベースはトランザクション情報に対してどのように結合を実行しますか?

4

3 に答える 3

5

Let's think on database table as B-Tree. Let me talk couple words on it datastructure - all we should know for your topic that B-tree is page organized. Assume you have 9 rows (marked from A..I) and B-tree with page size=3. Some way we have 3 pages on disk

Page1: A,B,C,
Page2: D,E,F
Page3: G,H,I

Assume you have changed something in row E. Your database connection will allocate memory for the page2 and totally load it (D..F). You made changes to E but transaction is not committed. Now you try to select (in the same connection). Since memory is already contains page loaded, your SELECT will see data that is modified. But if another connection will try load E it have to load to memory in-mutable D..F page2. After commit page2 is persisted, so all another connections could see changes.

Of course in real world the process much more complicated.

于 2012-12-06T16:12:12.280 に答える
2

次の記事を読むことをお勧めします。

SQL Server 2005 行のバージョン管理に基づくトランザクションの分離

この記事は特に Sql Server 2005 に関するものですが、さまざまな種類の同時実行制御の概要を示しています。

同時実行の制御に使用される主なモデルには、悲観的同時実行と楽観的同時実行の 2 つがあります。

悲観的同時実行制御ベースのシステムでは、ロックを使用して、ユーザーが他のユーザーに影響を与える方法でデータを変更することを防ぎます。ロックが適用されると、所有者がロックを解除するまで、他のユーザーはロックと競合するアクションを実行できません。このレベルの制御は、データの競合が多く、ロックを使用してデータを保護するコストが、同時実行の競合が発生した場合にトランザクションをロールバックするコストよりも小さい環境で使用されます。

逆に、オプティミスティック同時実行制御ベースのシステムでは、ユーザーはデータを読み取るときにデータをロックしません。更新が実行されると、システムは、読み取り後に別のユーザーがデータを変更したかどうかを確認します。別のユーザーがデータを更新すると、エラーが発生します。通常、エラーを受け取ったユーザーは、トランザクションをロールバックしてから、トランザクションを再送信します。これは、主にデータの競合が少なく、トランザクションを時々ロールバックするコストが読み取り時にデータをロックするコストを上回る環境で使用されるため、オプティミスティック コンカレンシーと呼ばれます。

行のバージョン管理を使用したコミット読み取り分離は、悲観的同時実行と楽観的同時実行の中間のどこかにあります。この分離レベルでは、読み取り操作はライブ データに対するロックを取得しません。ただし、更新操作では、この分離レベルのプロセスは、デフォルトの読み取りコミット分離レベルの場合と同じです。更新する行の選択は、データ行で更新ロックがデータとして取得されるブロッキング スキャンを使用して行われます。値が読み取られます。

一方、スナップショット分離は、変更されるデータが事前に実際にロックされるのではなく、変更のために選択された時点でロックされるため、非常に楽観的です。データ行が更新条件を満たしている場合、スナップショット トランザクションは、スナップショット トランザクションの開始後にデータが別のトランザクションによって変更されていないことを確認します。データが別のトランザクションによって変更されていない場合、スナップショット トランザクションはデータをロックし、データを更新し、ロックを解放して次に進みます。データが別のトランザクションによって変更されている場合、更新の競合が発生し、スナップショット トランザクションはロールバックします。

提案されたコメントのように、使用される同時実行制御のタイプは、使用されるデータベース プラットフォームによって異なるだけでなく、使用される設定に基づいてプラットフォーム内でも異なります。

于 2012-12-06T16:00:56.660 に答える
0

どのトランザクション分離レベルでも、同じトランザクションからダーティ データにアクセスできます。

于 2012-12-06T15:32:14.433 に答える