當兩件事情必須確實執行完畢,才存取到資料庫!
Transactions交易
像是銀行匯款,必須一方確實扣款,另一方確實有新增款項,這筆交易在算成功!
1 2 3 4 |
|
在 transaction 裡面必須使用加上 !
才會丟例外,讓交易失敗。
另外,資料要在 transaction 完成後,才會存取到資料庫,因此有用 after_save
回呼,可能就會失敗。
因此必須改用 after_commit
這個回呼,才能確保讀取到交易完成後的資料。
1 2 3 4 5 6 7 |
|
Isolation level
Transactions 又可以分成以下四種 level
隔離層級 | Dirty Read | Unrepeatable Read | Phantom Read |
---|---|---|---|
未提交讀(Read uncommitted) | YES | YES | YES |
已提交讀(Read committed) | NO | YES | YES |
可重複讀(Repeatable read) | NO | NO | YES |
可串行化(Serializable ) | NO | NO | NO |
提交讀(Read Committed)
- 能讀取到已經 commit 的 data。
- Oracle等多數數據庫預設都是該級別
- 換句話說,在這樣個 isolation level 下,不會有 “讀到別人還沒 commit 的 data” 這回事(dirty read)
未提交讀(Read uncommitted)
- 允許髒讀(dirty read),也就是可能讀取到其他會話中未提交事務修改的數據
可重複讀(Repeated Read)
- 可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB 預設級別。在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀
- 對於該 transaction 內讀過的 data, 在 transaction 的過程中不允許有別的 transaction 改動到這些 data。
串行讀(Serializable)
- 完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞
- 這是最進階的 isolation level。基本上可以想像使用這樣 isolation level 的 transaction,概念上可以視為同時間只有它一個 transaction 存在。
rails 指定 isolation level
1 2 3 4 5 6 7 8 |
|
參考文件: