5

自動コミットが有効になっている InnoDB に基づくすべてのテーブルを含む Mysql データベースでは、サブクエリおよび/または結合を含むクエリはアトミックになりますか?

例:

  • INSERT INTO users SELECT (x,y,z) FROM users, comments WHERE users.id = comments.user_id; (合流)

  • UPDATE users, comments SET users.x = x1 WHERE users.age > 30;(合流)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.age > 30;(合流)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.id IN (SELECT id FROM users WHERE age > 30);(サブクエリ)

4

4 に答える 4

9

「これらの各クエリはそれ自体がアトミック操作ですか?」というような質問は理解できます。その場合、答えは「はい」です。残りの 2 つの答えは正しいです。すべてのステートメントを一緒にするとアトミックではないと言う場合です。

データベースのアトミック性は、すべてかゼロかを意味するだけです。データの正確性を意味するものではありません。あなたのステートメントが成功するかどうか。結合やサブクエリとは関係ありません。データベースがメモリ内またはディスク上の一時テーブルを使用する必要があるかどうかに関係なく、1 つのステートメントは 1 つのステートメントです。

トランザクションは、複数のステートメントを 1 つのステートメントとして扱うようにデータベースに指示するだけです。ステートメントの 1 つが失敗すると、それらすべてがロールバックされます。

ここで重要な関連トピックは分離レベルです。あなたはそれらについて読みたいと思うかもしれません。

編集(コメントに答える):

それは正しい。それが有効なステートメントであり、電源障害が発生したり、クエリが失敗する可能性のあるその他の理由がない限り、クエリは実行されています。原子性自体は、ステートメントが実行されているかどうかを保証するだけです。完全性とデータが破損していないことを保証します (書き込み操作が完了しなかったなどの理由で)。データの正確性を保証するものではありません。次のようなクエリが与えられたINSERT INTO foo SELECT MAX(id) + 1 FROM bar;場合、正しい分離レベルを設定することで、ファントム読み取りなどを取得しないことを確認する必要があります。

于 2013-10-18T08:32:04.297 に答える
3

自動コミットをオンにすると、SQL ステートメントはアトミックに実行されません。自動コミットをオフにするには、トランザクションを開始する必要があります。http://dev.mysql.com/doc/refman/5.0/en/commit.htmlを参照してください。

于 2013-10-18T08:14:01.773 に答える
0

そうではないと思うので、その理由を説明します。私はMySQLで本当に奇妙な問題を抱えていました。

単一のレコードを持つ「table1」という名前のテーブルがあるとします。列 f1 の値は "A" です。列 f2 の値は「B」です

Update table1 set f1 = CONCAT(f1,f2), f2 = 'C';

f1 の最終値は、予想どおり 'AB' です。

ただし、順序を変更すると、次のようになります。

Update table1 set f2 = 'C', f1 = CONCAT(f1,f2);

f1 の最終値は「AC」です。つまり、最初に f2 が変更され、その後に f1 が変更されます。

私の結論は、更新操作は明らかに非原子的であるということです。f2 が最初に変更されます。f1 は、元の値ではなく、更新された f2 の値を使用した後に変更されます。

于 2017-12-14T23:36:06.013 に答える