成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

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

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

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

我們以經(jīng)典的轉(zhuǎn)賬例子來分別說明這幾個(gè)特性的詳細(xì)含義:A、B賬戶的余額都是一萬(wàn)元,然后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ù)庫(kù)從一個(gè)一致性狀態(tài)變成另外一個(gè)一致性狀態(tài)。在轉(zhuǎn)賬前,A、B賬戶的余額是一萬(wàn)元,合計(jì)是兩萬(wàn)元,轉(zhuǎn)賬后兩者的賬戶合計(jì)也必須是兩萬(wàn)元,如果轉(zhuǎn)賬所涉及的兩步操作有一步失敗,比如A賬戶減去1000元沒有成功,但B賬戶卻加上了1000元,那么事務(wù)結(jié)束后,兩者的余額合計(jì)就變成了兩萬(wàn)一千元,這時(shí)數(shù)據(jù)庫(kù)就處于不一致的狀態(tài)了。

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

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

二、MySQL中的事務(wù)

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

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

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

SHOW VARIABLES LIKE 'AUTOCOMMIT';

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

圖片圖片

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

SET AUTOCOMMIT=0;

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

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

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

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

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

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

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

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

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

我們用一個(gè)簡(jiǎn)單的例子來演示一下部分控制語(yǔ)句的用法,特別是關(guān)于保存點(diǎn)的用法,相對(duì)來講,它可能有點(diǎn)陌生。我們創(chuàng)建一個(gè)非常簡(jiǎn)單的表,并且往里面插入幾行數(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;
# 會(huì)發(fā)現(xiàn)最后一次更新沒有成功,因?yàn)樗换貪L了
SELECT * FROM t_employee WHERE id = 1

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

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

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

圖片圖片

下面我們用實(shí)例演示這四種隔離級(jí)別,首先創(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ù)隔離級(jí)別為讀未提交
  • 開始事務(wù)
  • 查詢客戶1002的余額為500

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級(jí)別為讀未提交
  • 開始事務(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ù)隔離級(jí)別為讀已提交
  • 開始事務(wù)
  • 查詢客戶1002的余額為500

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級(jí)別為讀已提交
  • 開始事務(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ù)隔離級(jí)別為可重復(fù)讀
  • 開始事務(wù)
  • 查詢表中的所有記錄,一共三條

Step2:事務(wù)B

圖片圖片

  • 設(shè)置當(dāng)前session的事務(wù)隔離級(jí)別為可重復(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ù)隔離級(jí)別為串行化
  •  開始事務(wù)
  • 查詢表中的所有記錄,一共三條

Step2:事務(wù)B

圖片圖片

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

圖片圖片

四、小結(jié)

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

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

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

2021-08-26 12:27:47

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

2017-08-22 17:10:45

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

2024-04-08 10:11:15

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

2020-06-17 16:56:36

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

2024-03-18 09:44:02

HashMap算法Java

2010-05-31 15:12:44

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

2018-08-01 14:00:49

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

2013-06-06 09:31:52

2010-05-14 14:38:03

安裝MySQL

2021-02-08 08:30:11

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

2024-01-18 09:43:11

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

2009-12-18 17:20:24

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

2009-09-24 14:12:22

Hibernate數(shù)據(jù)

2025-01-06 10:24:50

2010-10-08 09:38:55

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

2018-03-19 09:59:24

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

2023-04-12 08:04:09

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

2014-06-27 16:43:18

視頻會(huì)議終端華為

2018-07-20 11:10:21

數(shù)據(jù)庫(kù)事務(wù)隔離性

2023-10-11 08:09:53

事務(wù)隔離級(jí)別
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 久久爱一区| 中文在线a在线 | 欧美高清免费 | 国产成人精品一区二区三区视频 | 91久久久久久 | 在线不卡av| 嫩草懂你的影院入口 | 欧美视频xxx | 久久亚洲综合 | 日本一区二区三区免费观看 | 亚州精品天堂中文字幕 | 欧美日韩在线观看一区 | 操操日 | 久久国产99 | 天堂一区| 九九九久久国产免费 | 久久国产欧美日韩精品 | 国产精品一级在线观看 | 极品在线| 国产精品视频入口 | 免费一区二区三区在线视频 | 91观看 | 欧美成年黄网站色视频 | 免费不卡视频 | 日韩中字幕 | 日韩在线视频一区 | 日韩av三区 | 天堂视频免费 | 久久国产婷婷国产香蕉 | 懂色中文一区二区三区在线视频 | 亚洲视频免费在线观看 | 午夜视频在线免费观看 | 二区久久 | 亚洲欧美一区二区三区国产精品 | 国产欧美日韩视频 | 国产成人在线视频 | 精品视频一区二区 | 色综合一区二区三区 | 久久久精品天堂 | 日韩欧美中文字幕在线观看 | 欧美自拍一区 |