# 事務
> 官網:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-model.html
* **InnoDB 引擎**才支持事務
* 事務處理可以用來維護數據庫的完整性,保證成批的 SQL語句**要么全部執行,要么全部不執行**
* 事務需要滿足4個條件(**ACID**):**原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)**
* MySQL 默認自動提交事務
## **ACID**
事務正確執行的四要素:
* **原子性(Atomicity)**:
一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
* **一致性(Consistency)**:
在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及后續數據庫可以自發性地完成預定的工作。
* **隔離性(Isolation)**:
數據庫允許多個并發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致。
事務隔離分為不同級別,包括**讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)**。
* **持久性(Durability)**:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。
## **事務的隔離級別**
### **讀未提交(Read uncommitted)**
所有事務都可以看到沒有提交事務的數據。會造成**臟讀**問題。
### **讀已提交(Read committed)**
事務成功提交后才可以查詢到。
### **可重復讀(Repeatable read)**
InnoDB **默認的**隔離級別
同一事務中的**一致性讀取**讀取第一次讀取建立的[快照](https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_snapshot),這意味著,如果在同一個事務中發出幾個普通的(非鎖定的)`SELECT`語句,這些`SELECT`語句之間也是一致的。
對于鎖定讀取(`SELECT with FOR UPDATE` or `FOR SHARE`)、`UPDATE`、`DELETE`語句,鎖定取決于語句是使用具有唯一搜索條件的唯一索引還是范圍類型的搜索條件。
* 對于具有唯一搜索條件的唯一索引,InnoDB 只鎖定下找到的索引記錄,而不鎖定它之前的間隙。
* 對于其他搜索條件,InnoDB 鎖定掃描的索引范圍,使用**間隙鎖**或**下一個鍵鎖**來阻止其他會話插入該范圍所覆蓋的間隙。
### **串行化(Serializable)**
強制的進行排序,在每個讀讀數據行上添加**共享鎖**。會導致大量超時現象和鎖競爭
## **事務隔離產生的影響**
- **臟讀**:一個事務讀取到了另一個事務修改后還沒有提交的數據。
- **不可重復讀**:一個事務多次讀取同一數據時,有另外的事務進行修改提交,導致 **多次讀取同一數據結果不一致**。
- **幻讀**:一個事務中,多次 `SELECT` 查詢到不同的行,即在一次事務中,執行兩次 `SELECT` ,但第二次返回了第一次沒有返回的行。
> 為防止出現幻讀,InnoDB 中使用了一種稱為下一個鍵鎖定的算法,它結合了索引行鎖和間隙鎖。
## 一致非鎖定讀
一致性讀取意味著 InnoDB 使用多版本向查詢提供數據庫在某個時間點的快照。查詢會看到在該時間點之前提交的事務所做的更改,以及稍后或未提交的事務所做的更改。此規則的例外是查詢會看到同一事務中先前語句所做的更改。
此異常會導致以下異常:如果更新表中的某些行,則 `SELECT`看到更新行的最新版本,但它也可能看到任何行的舊版本。如果其他會話同時更新同一個表,則異常意味著您可能會看到該表處于數據庫中從未存在過的狀態。
如果事務隔離級別為 **REPEATABLE READ**(默認級別),則同一事務中的所有一致性讀取都會讀取該事務中第一次此類讀取所建立的快照。您可以通過提交當前事務并在此之后發出新查詢來獲得查詢的更新快照。
使用**READ COMMITTED**隔離級別,事務中的每個一致讀取都會設置并讀取自己的新快照。
一致讀取是 InnoDB處理 `SELECT`語句 **READ COMMITTED**和 **REPEATABLE READ**隔離級別的默認模式。一致讀取不會對其訪問的表設置任何鎖定,因此其他會話可以在對表執行一致讀取的同時自由修改這些表。
假設您在默認 **REPEATABLE READ**隔離級別下運行。當您發出一致讀取(即普通 `SELECT`語句)時, InnoDB 為您的事務提供一個時間點,根據該時間點您的查詢看到數據庫。如果另一個事務在分配您的時間點后刪除了一行并提交,您不會看到該行已被刪除。插入和更新的處理方式類似。
> 詳細:https://dev.mysql.com/doc/refman/5.6/en/innodb-consistent-read.html
- PHP
- PHP 核心架構
- PHP 生命周期
- PHP-FPM 詳解
- PHP-FPM 配置優化
- PHP 命名空間和自動加載
- PHP 運行模式
- PHP 的 Buffer(緩沖區)
- php.ini 配置文件參數優化
- 常見面試題
- 常用函數
- 幾種排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常見問題
- MySQL 索引
- 事務
- 鎖機制
- Explain 使用分析
- MySQL 高性能優化規范
- UNION 與 UNION ALL
- MySQL報錯:sql_mode=only_full_group_by
- MySQL 默認的 sql_mode 詳解
- 正則表達式
- Redis
- Redis 知識
- 持久化
- 主從復制、哨兵、集群
- Redis 緩存擊穿、穿透、雪崩
- Redis 分布式鎖
- RedisBloom
- 網絡
- 計算機網絡模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常見幾種網絡攻擊方式
- Nginx
- 狀態碼
- 配置文件
- Nginx 代理+負載均衡
- Nginx 緩存
- Nginx 優化
- Nginx 配置 SSL 證書
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 進程管理
- CentOS與Ubuntu系統區別
- Java
- 消息隊列
- 運維
- RAID 磁盤陣列
- 邏輯分區管理 LVM
- 業務
- 標準通信接口設計
- 業務邏輯開發套路的三板斧
- 微信小程序登錄流程
- 7種Web實時消息推送方案
- 用戶簽到
- 用戶注冊-短信驗證碼
- SQLServer 刪除同一天用戶重復簽到
- 軟件研發完整流程
- 前端
- Redux
- 其他
- 百度云盤大文件下載
- 日常報錯記錄
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客戶端無法連接SVN服務器,主機積極拒絕
- Python
- 基礎
- pyecharts圖表
- 對象
- 數據庫
- PySpark
- 多線程
- 正則
- Hadoop
- 概述
- HDFS