4

私がそうするとします(注:以下の構文はおそらく正しくありませんが、心配しないでください...それは要点を説明するためだけにあります)

Start Transaction
INSERT INTO table (id, data) VALUES (100,20), (100,30);
SELECT * FROM table WHERE id = 100;
End Transaction

したがって、selectの目標は、前の挿入によって挿入されたばかりのテーブルから、前のINSERTによってのみ挿入されたすべての情報を取得することです。

ここで、実行中にINSERTが実行された後、他のユーザーもid=100でINSERTを実行するとします。

トランザクションの次のステップのSELECTステートメントは、他のユーザーによって実行されたINSERTによって挿入された行も取得しますか、それともトランザクション内の前のINSERTによって挿入された2つの行を取得しますか?

ところで、私はMySQLを使用しているので、MySQLへの回答を調整してください

4

6 に答える 6

7

これは、DB 接続で使用されるトランザクション分離に完全に依存します。

MySQL 5.0認定スタディガイドによると

ここに画像の説明を入力

420 ページには、Isolation Levels によって処理される 3 つのトランザクション条件が記載されています。

  • ダーティ リードとは、別のトランザクションによって行われたコミットされていない変更を 1 つのトランザクションが読み取ることです。トランザクション T1 が行を変更するとします。トランザクション T2 が行を読み取り、T1 がそれ​​をコミットしていなくても変更を確認した場合、それはダーティ リードです。これが問題となる理由の 1 つは、T1 がロールバックした場合、変更は元に戻されますが、T2 はそれを認識しないためです。
  • 反復不可能な読み取りは、トランザクションが同じ取得を 2 回実行するが、毎回異なる結果を取得する場合に発生します。T1 がいくつかの行を読み取り、次に T2 がそれらの行のいくつかを変更し、変更をコミットするとします。T1 が行を再度読み取ったときに変更を確認すると、別の結果が得られます。最初の読み取りは反復不可能です。T1 は同じクエリから一貫した結果を得られないため、これは問題です。
  • ファントムとは、以前は見えなかった場所に現れる行です。T1 と T2 が開始し、T1 がいくつかの行を読み取るとします。T2 が新しい行を挿入し、T1 が再度読み取ったときにその行を確認した場合、その行はファントムです。

ページ 421 では、4 つのトランザクション分離レベルについて説明しています。

  • READ-UNCOMMITTED : トランザクションが、他のトランザクションによって行われたコミットされていない変更を参照できるようにします。この分離レベルでは、ダーティ リード、反復不可能なリード、およびファントムが発生する可能性があります。
  • READ-COMMITTED : コミットされた場合にのみ、トランザクションは他のトランザクションによって行われた変更を参照できます。コミットされていない変更は表示されません。この分離レベルでは、反復不可能な読み取りとファントムの発生が許可されます。
  • REPEATABLE READ (デフォルト) : トランザクションが同じ SELECT を 2 回発行したことを確認します。他のトランザクションによってコミットされた、またはコミットされていない変更に関係なく、両方の回で同じ結果が得られます。つまり、同じクエリの異なる実行から一貫した結果が得られます。一部のデータベース システムでは、REPEATABLE READ 分離レベルでファントムが許可されるため、別のトランザクションが SELECT ステートメント間の中間で新しい行を挿入すると、2 番目の SELECT でそれらが表示されます。これは InnoDB には当てはまりません。REPEATABLE READ レベルではファントムは発生しません。
  • SERIALIZABLE : あるトランザクションの影響を他のトランザクションから完全に分離します。これは REPEATABLE READ に似ていますが、あるトランザクションで選択された行は、最初のトランザクションが終了するまで別のトランザクションで変更できないという追加の制限があります。

分離レベルは、DB セッションに対してグローバルに、セッション内で、または特定のトランザクションに対して設定できます。

SET GLOBAL TRANSACTION ISOLATION LEVEL isolation_level;
SET SESSION TRANSACTION ISOLATION LEVEL isolation_level;
SET TRANSACTION ISOLATION LEVEL isolation_level;

ここで、isolation_level は次のいずれかの値です。

  • 'READ UNCOMMITTED'
  • 'READ COMMITTED'
  • 'REPEATABLE READ'
  • 'SERIALIZABLE'

ではmy.cnf、デフォルトも設定できます。

[mysqld]
transaction-isolation = READ-COMMITTED
于 2012-12-18T19:08:55.307 に答える
2

他のユーザーが同じ行を更新しているため、行レベルのロックが適用されます。したがって、彼はあなたの取引が終了した後にのみ変更を加えることができます. 挿入した結果セットが表示されます。お役に立てれば。

于 2012-12-18T17:22:39.643 に答える
2

干渉は、SQL データベース トランザクションに関してはあいまいな言葉です。トランザクションが表示できる行は、その分離レベルによって部分的に決定されます。

したがって、選択の目標は、前の挿入によって挿入されたばかりのテーブルからすべての情報を取得し、前の INSERT によってのみ取得することです...

先行挿入も少しぼやけています。

問題の挿入を読み取る前に、おそらくCOMMIT する必要があります。そうしないと、制御できない特定の条件下で、そのトランザクションがロールバックされ、id=100 の行が実際には存在しない可能性があります。

もちろん、コミット後は、他のトランザクションが「id」、「value」、またはその両方の値を自由に変更できます。(十分な権限がある場合、つまり。)

于 2012-12-18T17:42:07.830 に答える
0

トランザクションは、トランザクション内のステートメントが他のトランザクションからの干渉なしに実行されているように見えます。ほとんどのDBMS(MySQLを含む)は、トランザクションのACIDプロパティを維持します。あなたの場合、A for Atomicに関心があります。これは、DBMSによって、トランザクション内のすべてのステートメントが中断することなくアトミックに実行されているように見えることを意味します。

于 2012-12-18T17:20:34.440 に答える
0

効率上の理由から、開発者はトランザクションを相互に完全に分離するように設定しません。データベースは複数の分離レベル、つまりシリアライズ可能、反復可能読み取り、コミット済み読み取り、非コミット読み取りをサポートします。それらは、最も厳密なものから最も厳密でないもののリストです。

于 2012-12-18T17:56:04.107 に答える
0

有効になるのは、テーブル内の同じ行へのアクセスを必要とするユーザーだけです。それ以外の場合、ユーザーは影響を受けません。

ただし、行ロックは読み取りロックまたは書き込みロックになる可能性があるため、これは少し複雑です。

ここでは、InnoDBストレージ エンジンについて説明します。

于 2012-12-18T17:29:39.077 に答える