”コミット”の意味がググって調べてもよくわかりません。
コミットとはインサートしようとするものをsaveし、コミットされたものがインサートでdbに格納されるということとは違うのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
要は変更した内容を確定
するということです。
もう少し言うと、トランザクションの範囲内で変更したことを確定
します。
逆にトランザクションの範囲内で変更したことを取り消す
場合は、ロールバック
します。
それだけ。
投稿2016/09/23 00:30
総合スコア16998
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
総合スコア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総合スコア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総合スコア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総合スコア1636
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
「2フェーズコミット」で検索するといいかもしれません。
ひとつのテーブルだけをあれこれする場合はピンとこないかもですが、
複数のテーブルを更新する必要があって、後のテーブルで
何某かのエラーが出たら前のテーブル更新はナシにしたいなあ
って場合にありがたい機能です。
投稿2016/09/22 14:08
総合スコア7458
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
別にインサートには限りません。アップデートもコミットの対象となります。
狭い意味では「処理を確定させる」ということなのですが、もう少し詳しく言うと「トランザクションを確定させる」という処理になります。
「トランザクション」が何かというと、「意味的に不可分な一連の処理」となります。
よく出る例えが銀行口座間の資金の移動の話です。
A銀行の口座からB銀行の口座にお金を移すとき、A銀行側では残高を減らし、B銀行では残高を増やす必要がありますよね。
どちらか一方の銀行の処理だけ成功しても意味がないことはお分かりいただけると思います。
(一方で減らしたのにもう一方が増えてないとか、一方が増えたのにもう一方が減ってないとか)
全ての処理を完了し矛盾のない状態であることをDBに確定させるのが「コミット」という処理です。
投稿2016/09/22 12:20
総合スコア1894
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/23 03:08