質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

354閲覧

データベースの仕組みについて

panjaA

総合スコア67

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

2グッド

6クリップ

投稿2017/08/17 14:05

①select ✳︎ from table名:
で全てのデータを取得中に
②insert into table(a,b,c)values(1,2,3):
で新たなデータが登録された場合
①で取得したデータには②で登録したデータが含まれるのでしょうか?

根本的に勘違いしている可能性があるので、間違っている箇所がありましたらご指摘よろしくお願いします。

stereo_code, KiyoshiMotoki👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

私の考えも、トランザクション分離レベルによる、です。

ただし私は、Repeatable Read以下のファントムリードが生じる分離レベル(MySQLではRead Committed以下)であれば、①に②がINSERTしCOMMITした結果は含まれうると考えます。ファントムリードが発生するということはレンジロックがとられないので②は①の実行中にロック待ちせず実行可能であり(読み取りロック方式 & ページロックでの衝突や、読み取りロック & ロックエスカレーションが発生しない限り)、またその結果が①の実行中に現れることに関してRepeatable Readの定義の上で禁止もしていないはずだからです。

試しにDB2でCURSORを進めながら横からINSERTしてみましたが、INSERTされた行もSELECTされることを確認しました。

投稿2017/08/18 16:07

編集2017/08/18 16:18
SVC34

総合スコア1149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2017/08/18 16:33

はい、仰る通りです。 初心者マークが付いていたので、複雑な回答より、大枠で捉えてもらった方が良いという思いで回答したのが間違いでした。 正確には他の方の回答を参照してもらうことにして、私の回答で誤った表現部分は少し暈しておきますw
SVC34

2017/08/18 16:40

トランザクションの話はどうしても複雑になってしまいますね
SVC34

2017/08/21 07:09 編集

MVCCであっても、記載している通りファントムリードが発生するトランザクション分離レベルであれば影響を受けるはず、というのが私の考えです。①の途中に②が見えるというのは、トランザクション開始後にINSERTされた行が見えるということでファントムリードと実質同じことであると考えます。DB2も今はMVCCを導入しています。
shoko1

2017/08/21 08:04

OracleのようなMVCCではバージョン管理のため、①の処理のバージョンと②の処理のバージョンが異なり、①の結果に②の内容は含まれません。DB2のCS with CCはバージョン管理ではなく、トランザクションログからデータを取得するため後のトランザクション②のデータが①に含まれる可能性があります。のようにファントム・リードとは関係なくDBに実装によって結果は変わってしまいます。
shoko1

2017/08/21 09:31

いろいろ書いてますが、利用者レベルであればトランザクション分離レベルの認識で問題はないという部分は同意です。
guest

0

修正(断言的な記述を修正)

トランザクション分離レベルの設定次第です。

採用されているトランザクション分離レベルの多くはREAD COMMITTEDだと思うので、
その場合には、①を開始以降に②が行われても、①の結果には(ほぼ※)含まれません。
※含まれていたとしても、selectの結果行が増えるのと同じ結果になるなら特段の処理は不要だと思います。

但し、実際の環境についてどのトランザクション分離レベルを採用しているかの確認を取られた方が確実です。

投稿2017/08/17 14:23

編集2017/08/18 16:39
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suzukis

2017/08/18 01:04 編集

SELECTの途中でINSERTができ、すでに実行中のSELECTがその影響を受ける分離レベルはたとえばなんでしょうか。yubaさんの回答の通りSELECTが獲得するロックの話で、トランザクション分離レベルはそれには影響しないはずですが。 デフォルトのトランザクション分離レベルがシリアライザブルになってるRDBMSはたとえば何でしょうか。著名な物のほとんどはシリアライザブル以外になってるはずですが。
sazi

2017/08/18 11:30 編集

ご指摘ありがとうございます。 デフォルトのトランザクション分離レベルは、うろ覚えで回答してしまっていたので、修正しました。 実行中のselect ではトランザクション分離レベルによって、他のトランザクションでの追加・更新・削除により、ファントムリードやダーティリードになる場合があると理解していますが、誤った理解でしょうか? また、select 発行しただけでテーブルにロックが掛かるとは初耳なのですが。
KiyoshiMotoki

2017/08/18 11:53 編集

横から失礼します。 トランザクション分離レベルによってご質問の現象が発生するか否かは私には分かりませんが、 少なくとも、この手順ではファントムリード・ノンリピータブルリード・ダーティリードは発生しえません。 なぜなら、 ファントムリードとノンリピータブルリードは  1つのトランザクション内で同じ SELECT を【2回】実行したとき、1回目と2回目とで異なる結果になる現象 で、 ダーティリードは  【データを更新するトランザクションを先に】実行し、SELECT 後にロールバックすると発生する現象 だからです。 https://en.wikipedia.org/wiki/Isolation_(database_systems)#Read_phenomena もし、ご質問の現象が発生するとしても、それは上記3つのケースのいずれでもない何か、ということです。
sazi

2017/08/18 16:49 編集

Re:KiyoshiMotoki様 コメントありがとうございます。 自身の経験では、READ COMMITTEDの場合で、ファントムリードが問題となるような実装となる設計には普通ならないだろうという気がします。 なぜなら、同一のトランザクション内で同一のselectを発行することが無かったからです。 質問者様が心配しておられる同一テーブルへの複数回のSELECTの発行による不整合が現実にあり得るかどうかを考えた時、例えば、fetchによる2重ループの内と外で、それぞれAというテーブルを結合したSQLを発行した場合にはファントムリードによる不整合があり得る気がします。 ダーティーリードについては、「・・・ロールバックすると・・・」そういう対処の実装を行っているDBMSが何なのか把握していません。 今回質問者様は特定のDBMSに限定しているわけではなかったので ANSI/ISO SQL標準上では「更新途中で読取れる」こととなっているので、 その規格の範囲内ではあり得ることとして考えた方が良いのではと思います。 あくまで、議論としての発言で、反論という類ではありません。 配慮の欠けた発言がありましたら、ご容赦下さい。
suzukis

2017/08/19 03:27

トランザクション分離レベルというのは、複数のトランザクションが走る場合に、そのトランザクションの中の個々の操作がトランザクション間でどのように影響するするかを定義したものです。複数のSELECTを行うトランザクションの処理中に別のトランザクションのINSERTが割り込んだ(割り込もうとした)とした時にどうなるか、という話であればトランザクション分離レベルの話ですが、質問のようにSELECTを実行しそのデータを取得中にINSERTをしたらどうなるかというのはトランザクション分離レベルの関知するところではありません。DBの実装によってトランザクション分離レベルの実現をロックで行っている場合にそのことが間接的に影響する可能性はありますが、トランザクション分離レベルによってその動作が直接的に定義されてるわけではありません。
sazi

2017/08/19 05:45 編集

質問者様が誤解すると嫌なので書きますが、トランザクション分離レベルをDBMSのモード設定と同義に考えておられませんか? トランザクション分離レベルは規格であり、DBMSがどのように実現しているかは関係ありません。 (モード設定以外にも、テーブルロックやfor updateなども組み合わせて初めて実現するなど) 「SELECTを実行しそのデータを取得中にINSERTをしたらどうなるか」のような場合を含めた振る舞いを規格として定めたものがトランザクション分離レベルです。
sazi

2017/08/19 07:01 編集

>複数のSELECTを行うトランザクションの処理中に >別のトランザクションのINSERTが割り込んだ(割り込もうとした)とした時にどうなるか と >質問のようにSELECTを実行しそのデータを取得中にINSERTをしたらどうなるか の違いが分かりません。 後者は、質問の意図が、同一のトランザクション内での話だと言われているのですか? suzukis様のこの回答への最初のコメントではロックの話をされているので違うとは思いますが。
suzukis

2017/08/19 08:28

> 「SELECTを実行しそのデータを取得中にINSERTをしたらどうなるか」のような場合を含めた振る舞いを規格として定めたものがトランザクション分離レベル 違います。ここの理解がちがうなら話になりませんね。
sazi

2017/08/21 01:11 編集

私の認識が間違えているなら、それを正せるだけの情報が欲しかったのですが、違いますの一言だけなのは、この一連の記事が纏まりのないものになるので、非常に残念です。
shoko1

2017/08/21 01:08 編集

横からですが、A, Bとトランザクションがあった場合に、A.参照1→B.追加1→A.参照2と進んだときの参照1と参照2の結果が異なるという定義がファントム・リードです。A.参照1→B.追加1と進んでA.参照1が終わる前にB.追加1が終わった場合の参照1がどうなるかは定義されていません。 なので、ファントム・リードが起きるトランザクション分離レベルだからといって、参照1に追加1の内容が含まれる現象(ファントム・リードではない何か)が起きるかどうかはDBの実装によることになると思います。 ようするに、上記の現象(ファントム・リードではない何か)の結果がどうなろうともトランザクション分離レベルには関係がないということになります。
shoko1

2017/08/21 01:33

上はファントム・リードで書きましたが、ダーティ・リード、反復不可能読み取りでも同様です。 あと、Oracleだと起きません。
sazi

2017/08/21 01:35 編集

コメントありがとうございます。 ファントム・リードに対する認識が違うということですね。 そうやって、記事全体を見返してみると、辻褄があってきます。 回答に関わっている中で私だけが認識違いだったようです。 多分、KiyoshiMotoki様のリンク先をよく読めれば(英語だったので殆ど・・・)、認識の過ちに気付いていたのかもしれません。 精進致しますので、皆様ご容赦下さい。 特に、suzukis様、KiyoshiMotoki様には深くお詫びします。 shoko1様、ありがとうございました。
sazi

2017/08/21 01:42 編集

panjaA様、色々混乱させ、一番ご迷惑をおかけしたたことかと思います。 お詫び致します。
guest

0

DB製品によってロックの仕組みは異なるのですが、①のアクセス中にテーブルには読み取りロックがかかります。読み取りロックがかかったオブジェクトに対して別セッションは書き込みアクセスをできないため、②は①が終わるまで待たされることになります。

投稿2017/08/17 14:15

yuba

総合スコア5568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shoko1

2017/08/18 11:25 編集

読み取りロック方式はSQL Serverの初期設定で採用してる程度なので断言するような内容ではないと思います。MVCCの方が一般的ではないでしょうか。
panjaA

2017/08/18 11:33 編集

回答ありがとうございます! 1つ質問してもよろしいでしょうか。 http://gyouza-daisuki.hatenablog.com/entry/2013/11/19/150838 上記サイトで下記のような説明があったのですが、今回の私の質問を下記説明通りに考えると①で取得したデータには②で登録したデータが含まれると思います。 おそらく私が間違っているのはわかっているのですが、どこを勘違いしてるのかがわかりません。 助けてください!よろしくお願いします。 ファントムリード 別のトランザクションで挿入されたデータが見えることにより、一貫性がなくなる現象。 トランザクションAでレコードをSELECTする。該当レコードがない。 トランザクションBでレコードをINSERTし、COMMITする。 トランザクションAでレコードをSELECTする。2でINSERTとしたレコードが取得できる。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問