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

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

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

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

Q&A

解決済

8回答

14245閲覧

SQLのコミットの意味

terate

総合スコア103

SQL

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

0グッド

1クリップ

投稿2016/09/22 12:12

”コミット”の意味がググって調べてもよくわかりません。

コミットとはインサートしようとするものをsaveし、コミットされたものがインサートでdbに格納されるということとは違うのでしょうか?

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

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

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

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

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

guest

回答8

0

要は変更した内容を確定するということです。
もう少し言うと、トランザクションの範囲内で変更したことを確定します。
逆にトランザクションの範囲内で変更したことを取り消す場合は、ロールバックします。
それだけ。

投稿2016/09/23 00:30

ttyp03

総合スコア16998

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

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

Panzer_vor

2016/09/23 03:08

横から失礼致します。 当方も含め親切心からトランザクションの説明まで踏み込んだ回答が多くなってますが、「コミットとはなんぞや?」という質問の解としては一番的を射た回答な気がしますね。
guest

0

確かにファイルのSAVEとは似ていますが、ちょっと違います。

他の人の話にあるように、コミットだけではなく関連した幾つかの処理とセットで覚える必要があります。

例えば、DBに注文に注文を登録する処理があったとします。
(テーブル構成や処理順の妥当性できるなら無視してください)

例えば、注文はりんごを5個、みかんを3個として
1. 注文テーブルに注文日時・店舗・送付先などの情報をインサートします。
2. 在庫テーブルのりんごの行から、在庫数を5個減らします。
3. 注文明細テーブルにりんご5個を登録します。
4. 在庫テーブルのみかんの行から、在庫数を3個減らします。
5. 注文明細テーブルにみかん3個を登録します。
6. 1〜5の処理をDBにコミットします。

ここで1〜5の処理は、6がなければなかったことにしてくれます。
これがコミットです。ここまでの話はSAVEでも説明ができますね。
ただし、保存の対象がDBでもテーブルでもなく行単位だということが重要です。
また、複数の対象を同時に行うのも特徴です。

逆に問題があった場合、(例えば4でみかんの在庫が1個だったので、一旦りんごの注文もキャンセルする場合)はロールバックという処理をします。これも行単位で行われますが、SAVEのイメージで説明できます。

ところが、りんごの在庫処理(3)が済んだところで、別の注文でりんご4個の注文があった場合どうなるでしょうか?しかもりんごの在庫はあと7個です。

最初の注文で、在庫数は2個に減っています。しかし、コミットされていない関係で実際はキャンセルされて在庫はあるかもしれません。DBはどのように答えるのが正解でしょうか?

一般的には、先の注文がコミットかロールバックをするまで在庫の回答を行わないという動作をします。これを悲観的排他制御と呼びます。

楽観的排他制御の場合は、コミットした順が優先され後からコミットした方がエラーになります。
例えばEXCELのファイルを共有フォルダに置く場合は、楽観的排他制御になります。(後からSAVEした人に警告がでる。)

また、更新をする前に排他処理をかけることも出来ます。

排他制御には、あとデッドロックという覚えるべきことがらがありますが、ここでは割愛します。

とにかく、コミット・ロールバック・排他制御この3つをセットにしてトランザクションと呼び、
DBの”一貫性”を担保する機能として知られています。

投稿2016/09/22 14:01

iwamoto_takaaki

総合スコア2883

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

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

0

別解としてどう使うかの例を書いてみました。

最初にトランザクションを開始します。
以降の更新処理(insert, update, delete)は、commitするまで確定されません。
commitするまで、更新処理の内容は他のユーザには見えません。なので、データとして整合性が取れていない状態を発生されないようにできます。

sql

1start transaction; -- トランザクション開始 2insert into xxx ...; 3update xxx ...; 4delete from xxx ...; 5commit; -- ここで確定される

もし途中で更新処理をキャンセルしたくなったら、ロールバックすればできます。

sql

1start transaction; 2insert into xxx ...; 3update xxx ...; 4rollback; -- ロールバック(insertとupdateは実行しなかったことになる)

投稿2016/09/22 12:59

編集2016/09/22 13:00
popobot

総合スコア6586

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

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

0

ベストアンサー

他の方の回答と同じような内容になるかもしれませんが、私なりになるべく分かりやすいように言い換えてみたいと思います。

先の回答の例に似ていますが、銀行口座で、1つの口座に対して複数人が同時に入金/出金の処理を行うという話が典型例でしょうか。

  • ①残高10000円の口座にほぼ同時刻にAさんとBさんがアクセスします。

DBに格納されている実際の残高と、2人から見える残高は以下。

実際の残高 -> 10000円 A -> 10000円 B -> 10000円
  • ②Aさんが5000円の入金、Bさんが5000円の出金をそれぞれ試みます。

この時の残高の情報は以下。

実際の残高 -> 10000円 A -> 15000円 B -> 5000円
  • ③処理を確定します。

つまり、2人それぞれの参照している情報をDBに書き込みます。
ここでは2通りのパターンが考えられます。「Aさんが先に処理を確定するパターン」と、「Bさんが先に処理を確定するパターン」です。なお、話を簡単にするために「2人がまったくの同時刻に処理を確定するパターン」は考えません。

まず、前者のパターンを考えましょう。

Aさんが先に処理を確定する

②の時点での残高情報を再掲します。

実際の残高 -> 10000円 A -> 15000円 B -> 5000円

Aさんが処理を確定します。

実際の残高 -> 15000円 A -> 15000円 B -> 5000円

続いて、Bさんが処理を確定します。

実際の残高 -> 5000円 A -> 15000円 B -> 5000円

最終的な残高は5000円になりました。
しかし、元の残高が10000円、入金が5000円、出金が5000円なので、口座の残高10000円であるべきです。
これではユーザに5000円の損失があります。
困りますね。

前者のパターンでは良くなかったので、後者のパターンを考えましょう。

Bさんが先に処理を確定する

②の時点での残高情報を再掲します。

実際の残高 -> 10000円 A -> 15000円 B -> 5000円

Bさんが処理を確定します。

実際の残高 -> 5000円 A -> 15000円 B -> 5000円

続いて、Aさんが処理を確定します。

実際の残高 -> 15000円 A -> 15000円 B -> 5000円

最終的な残高は15000円になりました。
しかし、元の残高が10000円、入金が5000円、出金が5000円なので、口座の残高10000円であるべきです。
これでは銀行に5000円の損失があります。
困りますね。

両者のパターンで残高に矛盾が生じることが判明しました。
どうやら、単純に情報の参照・更新ができるだけのシステムでは、具合が悪いようです。

コミットの必要性

情報の整合性を保つためには、一方の処理を確定しつつ、もう一方の処理は破棄するのが無難でしょう。

今回のDBの情報の取得から更新までのように、一連の処理の開始から終了までを不可分のものとし、問題がなければ処理を確定、問題があれば処理を破棄という仕組が必要です。
この「一連の処理」のことを「トランザクション」といいます。
トランザクションの確定を「コミット」、破棄を「ロールバック」といいます。
コミットはDB内の情報の整合性を保つために必要なのです。

コミットというよりはトランザクション処理が重要だと考えたほうがいいかもしれませんが…。

投稿2016/09/22 16:14

編集2016/09/22 16:25
carimatics

総合スコア740

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

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

0

コミットとはトランザクションを確定させ、更新を永続化することです。

トランザクションとはデータベースの更新単位です。更新単位はアトミックな性質を持ちます。アトミック性とは、更新しなかったか、完全に更新したか、のどちらかであるという性質です。更新単位の一部だけが更新されることはありません。更新の内容は、業務要件により、コミット後にデータベースが整合性を保てるように決めます。トランザクションを終えるには、プログラムで、コミット(完全に更新する)か、ロールバック(全く更新しなかったことにする)します。

更新の永続化とは、いったんコミットした更新は、プログラムやマシンがクラッシュしても保証する(物理データベースに確実に書き込む)。コミットしなかった更新やロールバックした更新は、無かったことを保証します(物理データベースに中途半端な更新が書き込まれないこと)。

投稿2016/09/24 16:51

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

他の方もおっしゃっている通り、
コミットという所にのみ焦点を当てると仕組みが分かり辛いと思います。

データベースのトランザクションと呼ばれる仕組みを実現するための1つの機能にコミットと呼ばれるものが存在します。

他にトランザクションを支える仕組みとして、排他制御、ロールバックと呼ばれる機能も存在します。

少し専門的な単語を出しますが、
トランザクションではACID特性と呼ばれるものを担保する必要があります。
ACID特性をそれぞれ詳しく説明し出すと長くなるのでこちらを参考にすると分かりやすいかなと思います。
上記サイトではD:耐久性(永続性)の説明が見当たりませんが、
これは関して簡単に説明すると一度コミットしたデータはシステム障害がおこっても、
その時点まではデータを戻すことができることを保証する機能です。
(上記はリカバリの観点が絡んできますが)

掲示したサイトの例は規模がでかいのでもう少し身近な所でいうと、
商品在庫と出庫の関係が分かりやすいかなと思います。

以下出庫の場合のトランザクションについて考えてみます。

出庫のトランザクション開始前は

  • 商品Aの在庫は10個
  • 商品Aの出庫実績はなし

とすると商品Aを3つ出庫するトランザクションの結果は必ず下記のどちらかになります。

コミットした場合

  • 商品Aの在庫は7個
  • 商品Aの出庫実績は3個

ロールバックした場合

  • 商品Aの在庫は10個
  • 商品Aの出庫実績はなし

ここまでトランザクションという仕組みについて説明してきましたが、
逆にトランザクションという仕組みがないと、下記のような矛盾したデータが発生する可能性が出てきます。

例えば出庫実績だけ出来上がった場合、

  • 商品Aの在庫は10個
  • 商品Aの出庫実績は3個

上記のような半端な更新が起こると、
さも元々商品Aの在庫が13個あったような出庫前後で整合性が取れない状態となってしまいます。

このような状態となることを防ぐためにトランザクションという仕組みがあり、それを支える機能がコミット、ロールバック、排他制御となります。

ちなみにコミットという機能に絞って見ると、
ACID特性の中では主に、
ロールバックとペアでA(原子性)を、単体でD(永続性)を担っています。

投稿2016/09/22 16:32

編集2016/09/22 16:39
Panzer_vor

総合スコア1636

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

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

0

「2フェーズコミット」で検索するといいかもしれません。
ひとつのテーブルだけをあれこれする場合はピンとこないかもですが、
複数のテーブルを更新する必要があって、後のテーブルで
何某かのエラーが出たら前のテーブル更新はナシにしたいなあ
って場合にありがたい機能です。

投稿2016/09/22 14:08

takasima20

総合スコア7458

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

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

0

別にインサートには限りません。アップデートもコミットの対象となります。
狭い意味では「処理を確定させる」ということなのですが、もう少し詳しく言うと「トランザクションを確定させる」という処理になります。
「トランザクション」が何かというと、「意味的に不可分な一連の処理」となります。

よく出る例えが銀行口座間の資金の移動の話です。
A銀行の口座からB銀行の口座にお金を移すとき、A銀行側では残高を減らし、B銀行では残高を増やす必要がありますよね。
どちらか一方の銀行の処理だけ成功しても意味がないことはお分かりいただけると思います。
(一方で減らしたのにもう一方が増えてないとか、一方が増えたのにもう一方が減ってないとか)
全ての処理を完了し矛盾のない状態であることをDBに確定させるのが「コミット」という処理です。

投稿2016/09/22 12:20

ynakano

総合スコア1894

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

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

otn

2016/09/22 12:27

ちょっと例が良くないのでは?会社をまたがっての処理の整合性の話とRDBMSのコミットの話はずいぶんレベルが違います。
ynakano

2016/09/22 12:37

ご指摘の通りかもしれません。 銀行口座の話は色々なところで出てくるので「そんなもん」だと思って書いてた部分があります。 会社をまたがってしまう例は良くないですね。 トランザクションの例出の意図としては「一方を減らし、もう一方を増やす、処理を見ると2つだけどどちらか一方だけが成功しても意味がない処理」です。 いい具体例が出てこないですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問