《MySQL——事務》

目錄

  • 事務的必要性
  • MySQL中如何控制事務
  • 手動開啟事務
  • 事務的四大特征
    • 事務的四大特征
    • 事務開啟方式
    • 事務手動提交與手動回滾
  • 事務的隔離性
    • 臟讀現象
    • 不可重復讀現象
    • 幻讀現象
    • 串行化
  • 一些補充
    • 使用長事務的弊病
    • `commit work and chain`的語法是做什么用的?
    • 怎么查詢各個表中的長事務?
    • 如何避免長事務的出現?
    • 事務隔離是怎么通過read-view(讀視圖)實現的?
  • 參考

事務的必要性

mysql中,事務是一個最小的不可分割的工作單元。事務能夠保證一個業務的完整性。
比如我們的銀行轉賬:

-- a -> -100
UPDATE user set money = money - 100 WHERE name = 'a';-- b -> +100
UPDATE user set money = money + 100 WHERE name = 'b';

如果程序中,只有一條語句執行成功了,而另外一條沒有執行成功,就會出現前后不一致。就會有人白嫖。
因此,在執行多條有關聯 SQL 語句時,事務可能會要求這些 SQL 語句要么同時執行成功,要么就都執行失敗。
也就是說事務具有原子性。

MySQL中如何控制事務

1、mysql是默認開啟事務的(自動提交)
默認事務開啟的作用:

-- 查詢事務的自動提交狀態
SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
|            1 |
+--------------+

當我們執行一個sql語句時候,效果會立即體現出來,且不能回滾。
回滾舉例

CREATE DATABASE bank;USE bank;CREATE TABLE user (id INT PRIMARY KEY,name VARCHAR(20),money INT
);INSERT INTO user VALUES (1, 'a', 1000);SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

執行插入語句后數據立刻生效,原因是 MySQL 中的事務自動將它提交到了數據庫中。那么所謂回滾的意思就是,撤銷執行過的所有 SQL 語句,使其回滾到最后一次提交數據時的狀態。

在 MySQL 中使用 ROLLBACK 執行回滾:
由于所有執行過的 SQL 語句都已經被提交過了,所以數據并沒有發生回滾。

-- 回滾到最后一次提交
ROLLBACK;SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

將自動提交關閉后,可以數據回滾:

-- 關閉自動提交
SET AUTOCOMMIT = 0;-- 查詢自動提交狀態
SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
|            0 |
+--------------+

現在我們測試一下:

INSERT INTO user VALUES (2, 'b', 1000);-- 關閉 AUTOCOMMIT 后,數據的變化是在一張虛擬的臨時數據表中展示,
-- 發生變化的數據并沒有真正插入到數據表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+-- 數據表中的真實數據其實還是:
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+-- 由于數據還沒有真正提交,可以使用回滾
ROLLBACK;-- 再次查詢
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

可以使用COMMIT將虛擬的數據真正提交到數據庫中:

INSERT INTO user VALUES (2, 'b', 1000);
-- 手動提交數據(持久性),
-- 將數據真正提交到數據庫中,執行后不能再回滾提交過的數據。
COMMIT;-- 提交后測試回滾
ROLLBACK;-- 再次查詢(回滾無效了)
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+

總結

1、查看自動提交狀態: select @@AUTOCOMMIT;
2、設置自動提交狀態: set AUTOCOMMIT = 0;
3、手動提交: 在 @@AUTOCOMMIT = 0 時,可以使用commit 命令提交事務
4、事務回滾: 在 @@AUTOCOMMIT = 0 時,可以使用rollback 命令回滾事務

事務給我們提供了一個可以反悔的機會,假設在轉賬時發生了意外,就可以使用 ROLLBACK 回滾到最后一次提交的狀態。假設數據沒有發生意外,這時可以手動將數據COMMIT 到數據表中。

手動開啟事務

可以使用BEGIN 或者 START TRANSACTION 手動開啟一個事務。

-- 使用 BEGIN 或者 START TRANSACTION 手動開啟一個事務
-- START TRANSACTION;
BEGIN;
UPDATE user set money = money - 100 WHERE name = 'a';
UPDATE user set money = money + 100 WHERE name = 'b';-- 由于手動開啟的事務沒有開啟自動提交,
-- 此時發生變化的數據仍然是被保存在一張臨時表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |   900 |
|  2 | b    |  1100 |
+----+------+-------+-- 測試回滾
ROLLBACK;SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+

當然事務開啟之后,使用commit提交后就不能回滾了。

事務的四大特征

事務的四大特征

A 原子性:事務是最小的單位,不可以分割
C 一致性:事務要求同一事務中的sql語句,必須要保證同時成功或者同時失敗
I 隔離性:事務1 和事務2 之間是具有隔離性的
D 持久性:事務一旦結束(commit or rollback),就不可以返回

事務開啟方式

1、修改默認提交 set autocommit = 0;
2、begin
3、start transaction

事務手動提交與手動回滾

手動提交:commit
手動回滾:rollback

事務的隔離性

事務的隔離性:

1、read uncommitted; 讀未提交的
2、read committed; 讀已經提交的
3、repeatable read; 可以重復讀
4、serializable; 串行化

臟讀現象

read uncommitted的隔離級別下:
臟讀:一個事務讀到了另外有一個事務沒有提交的數據
實際開發不允許臟讀出現。
如果有兩個事務 a、b
a事務對數據進行操作,在操作的過程中,事務并沒有被提交,但是b可以看見a操作的結果。b看到轉賬到了,然后就不管了。后面a進行rollback操作,錢又回去了,完成白嫖。

不可重復讀現象

read committed的隔離級別下:
小王一開始開啟了一個事務,然后提交了幾個數據,然后出去抽煙。
在他抽煙的時候,小明在其他電腦上開啟了一個事務,然后對那個表提交了一個數據。
小王煙抽完了,然后統計表中數據,發現不對勁。前后不一致了。

幻讀現象

repeatable read;的隔離級別下:
事務a和事務b同時操作一張表,事務a提交的數據也不能被事務b讀到,就可以造成幻讀。
可以觀察如下步驟:
小明 在杭州 開啟一個事務;
小王 在北京 開啟一個事務;
小明 對table進行插入數據操作,然后commit;然后查看表,發現操作成功
小王在對table進行插入之前也查看表,然而并沒有小明插入的數據,于是乎他插入了同樣的一條數據,數據庫報錯。
小王很是疑惑,這就是幻讀現象。

串行化

serializable的隔離級別下:
當user表被事務a操作的時候,事務b里面的寫操作是不可以進行的,會進入排隊狀態(串行化)。
“讀-讀”在串行化隔離級別允許并發。
直到事務a結束之后,事務b的寫入操作才會執行。
串行化的問題是性能特差。
一般來說,隔離級別越高,性能越差。
MySQL默認隔離級別是:repeatable read;

一些補充

使用長事務的弊病

存儲空間上來說:
長事務意味著系統里面會存在很老的事務視圖。由于這些事務隨時可能訪問數據庫里面的任何數據,所以這個事務提交之前,數據庫里面它可能用到的回滾記錄都必須保留,這就會導致大量占用存儲空間。
長事務還占用鎖資源,也可能拖垮整個庫。

commit work and chain的語法是做什么用的?

提交上一個事務,并且再開啟一個新的事務。它的功能等效于:commit + begin

怎么查詢各個表中的長事務?

這個表中記錄了所有正在運行的事務信息,里面有事務的開始時間。可以從這里看出哪些事務運行的時間比較長。

select * from information_schema.innodb_trx;

如何避免長事務的出現?

數據庫方面:

a.設置autocommit=1,不要設置為0。
b.寫腳本監控information_schemal.innodb_trx表中數據內容,發現長事務,kill掉它。
c.配置SQL語句所能執行的最大運行時間,如果查過最大運行時間后,中斷這個事務

SQL語句方面:

設置回滾表空單獨存放,便于回收表空間

業務代碼方面:

1、檢查業務邏輯代碼,能拆分為小事務的不要用大事務。
2、檢查代碼,把沒有必要的select語句被事務包裹的情況去掉

事務隔離是怎么通過read-view(讀視圖)實現的?

每一行數有多個版本,當我們要去讀取數據的時候,要判斷這個數據的版本號,對當前事務而言,是否可見,如果不可見,則要根據回滾日志計算得到上一個版本。如果上一個版本也不符合要求,則要找到再上一個版本,
直到找到對應正確的數據版本。

參考

一天學會MySQL
https://time.geekbang.org/column/article/68963

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377267.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

運行在TQ2440開發板上以及X86平臺上的linux內核編譯

一、運行在TQ2440開發板上的linux內核編譯 1、獲取源碼并解壓 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源碼包。 解壓(天嵌默認解壓到/opt/EmbedSky/linux-2.6.30.4/中) tar xvjf linux-2.6.30.4_20100531.tar.bz2 -C / 2、獲取默認配置…

ArcCatalog ArcMap打不開

原來是因為: 連接了電信的無線網卡 關掉即可 啟動ArcCatalog之后再開啟無線網卡 沒問題!轉載于:https://www.cnblogs.com/ccjcjc/archive/2012/08/21/2649867.html

Python熊貓– GroupBy

Python熊貓– GroupBy (Python Pandas – GroupBy) GroupBy method can be used to work on group rows of data together and call aggregate functions. It allows to group together rows based off of a column and perform an aggregate function on them. GroupBy方法可用…

MySQL索引底層原理理解以及常見問題總結

目錄二叉查找樹為索引紅黑樹為索引B樹作為索引B樹作為索引MyISAM存儲引擎索引實現InnoDB存儲引擎索引實現常見問題聚集索引與非聚集索引InnoDB基于主鍵索引和普通索引的查詢有什么區別?InnoDB主鍵索引為何是整型的自增主鍵何時使用業務字段作為主鍵呢?哈…

Spring之HibernateTemplate 和HibernateDaoSupport

spring提供訪問數據庫的有三種方式: HibernateDaoSupport HibernateTemplate(推薦使用) jdbcTemplate(我們一般不用) 類所在包: HibernateTemplate:org.springframework.orm.hibernate3.HibernateTemplate …

JDOJ-重建二叉樹

這是一道面試題,可以說是數據結構中的基礎題了,由先序遍歷以及中序遍歷生成一棵樹,然后輸出后序遍歷。 一個遞歸函數傳遞5個參數,頂點編號,先序左右區間,中序左右區間,每次進行區間長度判定&…

des算法密碼多長_密碼學中的多個DES

des算法密碼多長This is a DES that was susceptible to attacks due to tremendous advances in computer hardware in cryptography. Hence, it was a very complex or competent algorithm it would be feasible to reuse DES rather than writing an of cryptography. 由于…

《MySQL——索引筆記》

目錄回表覆蓋索引最左前綴原則聯合索引的時候,如何安排索引內的字段順序?索引下推重建索引問題聯合主鍵索引和 InnoDB 索引組織表問題in與between的區別回表 回到主鍵索引樹搜索的過程,我們稱為回表。 覆蓋索引 覆蓋索引就是在這次的查詢中…

計算凸多邊形面積的算法

1. 思路: 可以將凸多邊形(邊數n > 3)劃分為 (n - 2) 個三角形,分別運用向量叉積計算每個三角形的面積,最后累加各個三角形的面積就是多邊形的面積。 2. 求多邊形面積的算法模板:   定義點的結構體 str…

Windows CE開發常見問題解答

轉自: http://blog.csdn.net/slyzhang/article/details/6110490 1.怎樣在一個控件獲得焦點時打開軟鍵盤?比如一個EditBox獲得焦點后,這個時候自動打開軟鍵盤,這樣可以方便用戶輸入——SIPINFO、SHSIPINFO、SIPSETINFO、SIPGETINFO…

Julia中的supertype()函數

Julia| supertype()函數 (Julia | supertype() function) supertype() function is a library function in Julia programming language, it is used to get the concrete supertype of the given type (data type). supertype()函數是Julia編程語言中的庫函數,用于…

《操作系統知識點整理》

目錄進程與線程比較多線程同步與互斥生產者與消費者哲學家就餐問題讀者寫者問題進程間通信管道消息隊列共享內存信號量信號Socket鎖互斥鎖與自旋鎖讀寫鎖樂觀鎖與悲觀鎖死鎖進程與線程比較 進程是資源(包括內存、打開的文件等)分配的單位,線…

for,foreach,iterator的用法和區別

相同點&#xff1a; 三個都可以用來遍歷數組和集合不同點&#xff1a;1.形式差別 for的形式是 for&#xff08;int i0;i<arr.size();i&#xff09;{...} foreach的形式是 for&#xff08;int i&…

和菜鳥一起學linux總線驅動之初識spi驅動主要結構

既然知道了協議了&#xff0c;那么就可以開始去瞧瞧linux kenerl中的spi的驅動代碼了&#xff0c;代碼中有很多的結構體&#xff0c;還是對主要的結構體先做個了解吧&#xff0c;那樣才可以很好的理解驅動。主要是include/linux/spi.h 首先是SPI的主機和從機通信接口&#xff0…

操作系統大內核和微內核_操作系統中的內核

操作系統大內核和微內核A Kernel is the central component of an Operating System. The Kernel is also said to be the heart of the Operating System. It is responsible for managing all the processes, memory, files, etc. The Kernel functions at the lowest level …

《MySQL——鎖》

全局鎖是什么&#xff1f;全局鎖有什么用&#xff1f;全局鎖怎么用&#xff1f; 全局鎖主要用在邏輯備份過程中&#xff0c;對于InnoDB 引擎的庫&#xff0c;使用–single-transaction; MySQL 提供了一個加全局讀鎖的方法&#xff0c;命令是 Flush tables with read lock (FTW…

搜索引擎Constellio及Google Search Appliances connectors

做搜索產品的時候發現國外一個同類型的產品contellio&#xff0c;發現功能比較強大&#xff0c;先記錄下來 貌似可以添加文檔 網站 以及數據庫等不同類型的數據源 http://wiki.constellio.com/index.php/Main_Page http://www.constellio.com/ http://www.constellio.com htt…

dig下載_DIG的完整形式是什么?

dig下載DIG&#xff1a;副監察長 (DIG: Deputy Inspector General) DIG is an abbreviation of the Deputy Inspector General. It is a high-level position in the Indian Police Service. The officers who already offered service on Senior Superintendent of Police (SS…

分類器是如何做檢測的?——CascadeClassifier中的detectMultiScale函數解讀

原地址&#xff1a;http://blog.csdn.net/delltdk/article/details/9186875 在進入detectMultiScal函數之前&#xff0c;首先需要對CascadeClassifier做初始化。 1. 初始化——read函數 CascadeClassifier的初始化很簡單&#xff1a; cv::CascadeClassifier classifier; cl…

<MySQL>何時使用普通索引,何時使用唯一索引

如果能夠保證業務代碼不會寫入重復數據&#xff0c;就可以繼續往下看。 如果業務不能保證&#xff0c;那么必須創建唯一索引。 關于查詢能力 普通索引和唯一索引在查詢能力上是沒有很大差別的。 如&#xff1a;select id from T where k5 1、普通索引查找到滿足條件的第一個記…