自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL探秘之旅:繞不開的數(shù)據(jù)庫事務(wù)

數(shù)據(jù)庫 MySQL
不論是日常編程,還是在面試當(dāng)中,數(shù)據(jù)庫事務(wù)都是繞不開的一個(gè)話題,所以有必要深入掌握,特別是它的隔離級別,也是經(jīng)常被經(jīng)常問起的問題。?

怎么強(qiáng)調(diào)數(shù)據(jù)庫事務(wù)的重要性都不為過,如果你還不知道、還沒有使用過事務(wù),那么你可能連初級程序員都算不上。

一、什么是數(shù)據(jù)庫事務(wù)

數(shù)據(jù)庫事務(wù)是用戶定義的一個(gè)數(shù)據(jù)庫操作序列,這些操作要么全做要么全不做,是一個(gè)不可分割的工作單位。

事務(wù)具有四個(gè)特性:原子性(Atomicity),一致性(Consistency),隔離性(Isolation)和持久性(Durability),簡稱ACID特性。

我們以經(jīng)典的轉(zhuǎn)賬例子來分別說明這幾個(gè)特性的詳細(xì)含義:A、B賬戶的余額都是一萬元,然后A賬戶向B賬戶轉(zhuǎn)賬1000元,這實(shí)際上包括了兩步操作,先是A賬戶減去1000元,變成了9000元,而B賬戶加上1000元,變成了11000元。

1. 原子性:事務(wù)中包含的操作要么全都做,要么全都不做。比如上面的轉(zhuǎn)賬例子,要么A賬戶減少1000元且B賬戶增加了1000元,要么兩個(gè)賬戶的余額都沒有改變。

2. 一致性:事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變成另外一個(gè)一致性狀態(tài)。在轉(zhuǎn)賬前,A、B賬戶的余額是一萬元,合計(jì)是兩萬元,轉(zhuǎn)賬后兩者的賬戶合計(jì)也必須是兩萬元,如果轉(zhuǎn)賬所涉及的兩步操作有一步失敗,比如A賬戶減去1000元沒有成功,但B賬戶卻加上了1000元,那么事務(wù)結(jié)束后,兩者的余額合計(jì)就變成了兩萬一千元,這時(shí)數(shù)據(jù)庫就處于不一致的狀態(tài)了。

3. 隔離性:多個(gè)事務(wù)可以并發(fā)執(zhí)行,但事務(wù)之間不能相互干擾,以確保一個(gè)事務(wù)的操作不會影響到另外一個(gè)事務(wù)。

4. 持久性:指事務(wù)一旦提交,它對數(shù)據(jù)庫中數(shù)據(jù)的影響是永久性的,接下來的其他操作或者故障不應(yīng)該對執(zhí)行結(jié)果有任何影響。

二、MySQL中的事務(wù)

在MySQL的架構(gòu)體系中,最下面一層是存儲引擎層,它負(fù)責(zé)數(shù)據(jù)的存儲和提取,通過命令show engines可以查看當(dāng)前服務(wù)器支持的存儲引擎:

由上圖可以看出,只有InnoDB存儲引擎才支持事務(wù),而它也是MySQL 5.7默認(rèn)的選項(xiàng),其它存儲引擎都不支持事務(wù)。NDB Cluster也支持事務(wù),它是基于內(nèi)存的存儲引擎,需要另行安裝,本文暫不討論。

MySQL默認(rèn)采用自動提交(AUTOCOMMIT)模式,即使沒有手動開啟事務(wù)(START TRANSACTION),MySQL也會默認(rèn)將當(dāng)前的每個(gè)SQL語句當(dāng)成一個(gè)事務(wù)進(jìn)行提交,可通過以下語句查詢當(dāng)前連接的自動提交模式:

SHOW VARIABLES LIKE 'AUTOCOMMIT';

從以上語句的執(zhí)行結(jié)果可以看到,這個(gè)參數(shù)默認(rèn)是ON,也就是開啟了自動提交模式:

圖片圖片

如果需要關(guān)閉自動提交模式,則把它設(shè)置為零即可,1或者ON表示啟用,0或者OFF表示關(guān)閉:

SET AUTOCOMMIT=0;

自動模式關(guān)閉以后,就需要手動開啟并提交或者回滾事務(wù)。

三、MySQL事務(wù)控制語句

BEGIN或START TRANSACTION:開啟一個(gè)新事務(wù)

COMMIT:提交當(dāng)前事務(wù),讓SQL語句對數(shù)據(jù)庫的修改成為永久性的

ROLLBACK:回滾當(dāng)前事務(wù),撤銷對數(shù)據(jù)庫的修改

SAVEPOINT identifier:保存點(diǎn),可以使用它回滾部分指定事務(wù),從而可以更精細(xì)的控制事務(wù),identifier為保存點(diǎn)的名稱

ROLLBACK TO SAVEPOINT:事務(wù)回滾到指定的保存點(diǎn)

RELEASE SAVEPOINT:刪除事務(wù)的保存點(diǎn)

SET TRANSACTION:用于指定事務(wù)的特性,比如隔離級別、訪問模式(讀寫/只讀)等。

我們用一個(gè)簡單的例子來演示一下部分控制語句的用法,特別是關(guān)于保存點(diǎn)的用法,相對來講,它可能有點(diǎn)陌生。我們創(chuàng)建一個(gè)非常簡單的表,并且往里面插入幾行數(shù)據(jù):

CREATE TABLE `t_employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `t_employee` (`name`) VALUES ('Tom');
INSERT INTO `t_employee` (`name`) VALUES ('John');
INSERT INTO `t_employee` (`name`) VALUES ('Hans');
# 開啟一個(gè)事務(wù)
START TRANSACTION;
# 更新id為1的name字段
UPDATE t_employee SET name='full stack' WHERE id = 1;
# 確認(rèn)更新成功
SELECT * FROM t_employee WHERE id = 1;
# 設(shè)置一個(gè)保存點(diǎn),名稱為s1
SAVEPOINT s1;
# 再次更新id為1的name字段
UPDATE t_employee SET name='full stack new' WHERE id = 1;
SELECT * FROM t_employee WHERE id = 1;
# 回滾事務(wù)到保存點(diǎn)s1
ROLLBACK TO s1;
# 會發(fā)現(xiàn)最后一次更新沒有成功,因?yàn)樗换貪L了
SELECT * FROM t_employee WHERE id = 1

如果執(zhí)行上面的SQL有錯(cuò)誤,請按照提示刪除多余的換行符。

四、事務(wù)隔離級別

上面我們提到過,事務(wù)有四大特性,其中一個(gè)是隔離性,在并發(fā)執(zhí)行事務(wù)的情況,可能會存在事務(wù)之間相互干擾的情況,這時(shí)候就需要指定合適的隔離級別,來保證程序運(yùn)行的正確性。事務(wù)隔離級別是指多個(gè)事務(wù)同時(shí)操作數(shù)據(jù)庫時(shí),事務(wù)之間相互隔離的程度,SQL 92規(guī)范有四種隔離級別,MySQL InnoDB存儲引擎也支持這四種級別,它們分別是:讀未提交,讀已提交,可重復(fù)讀,串行化。

圖片圖片

下面我們用實(shí)例演示這四種隔離級別,首先創(chuàng)建一個(gè)表并接入記錄:

CREATE TABLE `checking` (
  `customer_id` int(11) NOT NULL,
  `customer_name` varchar(255) DEFAULT NULL,
  `balance` decimal(16,4) DEFAULT NULL,
  `create_date` datetime DEFAULT NULL,
  `update_date` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`customer_id`),
  KEY `idx_customer_id` (`customer_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of checking
-- ----------------------------
INSERT INTO `checking` VALUES ('1002', 'Jane', '500.0000', '2024-11-01 09:57:08', '2024-11-08 16:34:09');
INSERT INTO `checking` VALUES ('1003', 'Tom', '300.0000', '2024-11-01 09:57:08', '2024-11-08 16:34:09');
INSERT INTO `checking` VALUES ('1004', 'John', '600.0000', '2024-11-01 09:57:08', '2024-11-08 16:34:09');

1.讀未提交

Step1:事務(wù)A

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為讀未提交
  • 開始事務(wù)
  • 查詢客戶1002的余額為500

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為讀未提交
  • 開始事務(wù)
  • 更新客戶1002的余額為800
  • 事務(wù)還沒有提交

Step3:事務(wù)A

圖片圖片

  • 再次查詢客戶1002的余額為,值800
  • 盡管事務(wù)B還沒有提交
  • 如果事務(wù)B回滾了,那么事務(wù)A查詢到的信息就臟數(shù)據(jù)

2.讀已提交

Step1:事務(wù)A

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為讀已提交
  • 開始事務(wù)
  • 查詢客戶1002的余額為500

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為讀已提交
  • 開始事務(wù)
  • 更新客戶1002的余額為800
  • 事務(wù)還沒有提交

Step3:事務(wù)A

圖片圖片

  • 再次查詢客戶1002的余額,值仍然為500
  • 事務(wù)B還沒有提交,所以解決了臟讀的問題

Step4:事務(wù)B

圖片圖片

  • 提交事務(wù)
  • 確認(rèn)余額為800

Step5:事務(wù)A

圖片圖片

  • 再次查詢客戶1002的余額,值變成了800
  • 事務(wù)A并還沒有提交,但這次讀到的數(shù)據(jù)不一樣了,產(chǎn)生不可重復(fù)讀的問題

3.可重復(fù)讀

Step1:事務(wù)A

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為可重復(fù)讀
  • 開始事務(wù)
  • 查詢表中的所有記錄,一共三條

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為可重復(fù)讀
  • 開始事務(wù)
  • 向表中插入一條記錄,customer_id=1100

Step3:事務(wù)A

圖片圖片

  • 不管事務(wù)B有沒有提交,都查不到事務(wù)B插入的數(shù)據(jù)
  • 避免了不可重復(fù)讀的問題,通過MVCC機(jī)制實(shí)現(xiàn)

Step4:事務(wù)A

圖片圖片

  • 把customer_id為1100的余額更新為460
  • 再次查詢,發(fā)現(xiàn)表中有了四條記錄,產(chǎn)生了幻讀
  • 可以通過加鎖讀取最新的數(shù)據(jù)

4.串行化

Step1:事務(wù)A

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為串行化
  •  開始事務(wù)
  • 查詢表中的所有記錄,一共三條

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級別為串行化
  • 開始事務(wù)
  • 向表中插入一條新的記錄
  • 最后提示超時(shí)的錯(cuò)誤
  • 串行化會強(qiáng)制把事務(wù)按照串行的方式執(zhí)行,效率很低

圖片圖片

四、小結(jié)

以上就是關(guān)于MySQL數(shù)據(jù)庫事務(wù)的內(nèi)容,從事務(wù)的含義和特性開始講解,接下來是MySQL對于事務(wù)的控制語句,最后再詳細(xì)說明數(shù)據(jù)庫的隔離級別,并用實(shí)例演示它的含義。

不論是日常編程,還是在面試當(dāng)中,數(shù)據(jù)庫事務(wù)都是繞不開的一個(gè)話題,所以有必要深入掌握,特別是它的隔離級別,也是經(jīng)常被經(jīng)常問起的問題。

責(zé)任編輯:武曉燕 來源: 互聯(lián)網(wǎng)全棧架構(gòu)
相關(guān)推薦

2021-08-26 12:27:47

云數(shù)據(jù)庫數(shù)據(jù)庫云計(jì)算

2024-04-08 10:11:15

MYSQL數(shù)據(jù)庫事務(wù)

2020-06-17 16:56:36

數(shù)據(jù)庫MySQL跨行事務(wù)

2017-08-22 17:10:45

數(shù)據(jù)庫MySQL事務(wù)模型

2010-05-31 15:12:44

MySQL數(shù)據(jù)庫

2024-03-18 09:44:02

HashMap算法Java

2018-08-01 14:00:49

MySQL數(shù)據(jù)庫PHP

2010-05-14 14:38:03

安裝MySQL

2013-06-06 09:31:52

2021-02-08 08:30:11

容器化云原生微服務(wù)

2024-01-18 09:43:11

MySQL數(shù)據(jù)庫

2025-01-06 10:24:50

2018-03-19 09:59:24

數(shù)據(jù)保護(hù)大數(shù)據(jù)云計(jì)算

2010-10-08 09:38:55

Android數(shù)據(jù)庫事

2009-09-24 14:12:22

Hibernate數(shù)據(jù)

2014-06-27 16:43:18

視頻會議終端華為

2023-04-12 08:04:09

MapReduce大數(shù)據(jù)框架

2009-12-18 17:20:24

ADO數(shù)據(jù)庫

2023-10-11 08:09:53

事務(wù)隔離級別

2018-07-20 11:10:21

數(shù)據(jù)庫事務(wù)隔離性
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號