# トランザクションについて # 伝えたいこと - ACIDの原子性とは、トランザクション内でのQueryを適用か不適用か - エラー発生時にトランザクションのCommit/RollBackをどう取り扱うかは、アプリケーションの責務である # 発端 [プログラミングスクール](https://www.value-press.com/pressrelease/247307)でメンターやってます。 「SQLゼロからはじめるデータベース操作」を読んだ、生徒さんからの質問がありました。 > PostgreSQLではトランザクションの中のSQL文が一つでもエラーになると、後続のSQL文も全てエラーになり強制的にロールバックする。 > PostgreSQL以外はエラーとなるSQL文だけが実行されず、それ以外のSQL文は実行されてコミットされる。例えばトランザクションの中で、3つのSQL文の内1つがエラーになっても2つは実行されてコミットされる。 上記からPostgreSQLを除くRDBMSは、原子性を守ることができないはないか? # トランザクション内でエラーが発生した際の挙動がPostgreSQL、MySQLで異なる 初動では、書籍の出版が古くACID特性がないMyISAMを紹介していると推測し、InnoDBの動作確認したところ思わぬ挙動を発見しました。 ```sql Insert into users (email) values ("imaharu@example.com"); START TRANSACTION; Insert into users (email) values ("imaharu@example.com"); Insert into users (email) values ("hoge@example.com"); commit; select count(*) from users; # 2 ``` 試しに、PostgreSQLの挙動を確認すると失敗した場合に後述のクエリ実行のエラーになり、RollBackすることがわかりました。 ```sql BEGIN; Insert into users (email) values ('imaharu@example.com'); ERROR: duplicate key value violates unique constraint "users_email_key" DETAIL: Key (email)=(imaharu@example.com) already exists. Insert into users (email) values ('hoge@example.com'); ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; ROLLBACK select count(*) from users; # 1 ``` # 実験(LTのみ) やる # 原子性に関する認識 ## 過去 トランザクション内で全てはクエリは、成功か失敗 トランザクション内でエラーが発生した場合、発行したクエリをRollBack。 ## 現在 トランザクション内のクエリを適用か不適用 # 回答結論 トランザクション内で発生した際の挙動は、アプリケーションの責務である。 DataBaseはトランザクションを制御するためのインターフェースを提供する。 # 調査してないこと - 非対話実行では、挙動が異なる - [RollBackは、PostgreSQL特有の挙動説](https://www.postgresql.jp/sites/default/files/2017-05/Introdution_to_Transaction_20170527d.pdf) ## 次回のLTで発表したいこと - MySQLのグローバル変数とセッション変数 - ActiveRecord::Transactionsの実装を紹介 - ロック - 占有ロック、共有ロック - ロックとは、トランザクション分離レベルを制御する機能 - トランザクション分離レベル # サンプルコード https://github.com/imaharu/mysql_test ## 議論メモ - https://twitter.com/imaharuTech/status/1278834000367247360?s=20 - https://twitter.com/zipperpull/status/1278845103180615680?s=20 - https://www.value-press.com/pressrelease/247307 ## 参考 https://dev.mysql.com/doc/refman/5.6/ja/myisam-storage-engine.html https://dev.mysql.com/doc/refman/5.6/ja/innodb-default-se.html https://dev.mysql.com/doc/refman/5.6/ja/glossary.html#glos_transaction https://www.postgresql.jp/document/12/html/tutorial-transactions.html https://qiita.com/song_ss/items/38e514b05e9dabae3bdb https://open-groove.net/mysql/autocommit https://atsuizo.hatenadiary.jp/entry/2019/02/26/142814
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.