# トランザクションについて
# 伝えたいこと
- 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