新聞中心
數(shù)據(jù)庫(kù)的事務(wù)機(jī)制是什么
回答的有點(diǎn)多請(qǐng)耐心看完。
目前累計(jì)服務(wù)客戶(hù)上千,積累了豐富的產(chǎn)品開(kāi)發(fā)及服務(wù)經(jīng)驗(yàn)。以網(wǎng)站設(shè)計(jì)水平和技術(shù)實(shí)力,樹(shù)立企業(yè)形象,為客戶(hù)提供網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷(xiāo)、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。成都創(chuàng)新互聯(lián)公司始終以務(wù)實(shí)、誠(chéng)信為根本,不斷創(chuàng)新和提高建站品質(zhì),通過(guò)對(duì)領(lǐng)先技術(shù)的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究、對(duì)客戶(hù)形象的視覺(jué)傳遞、對(duì)應(yīng)用系統(tǒng)的結(jié)合,為客戶(hù)提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶(hù),共同發(fā)展進(jìn)步。
希望能幫助你還請(qǐng)及時(shí)采納謝謝
1事務(wù)的原理
事務(wù)就是將一組SQL語(yǔ)句放在同一批次內(nèi)去執(zhí)行,如果一個(gè)SQL語(yǔ)句出錯(cuò),則該批次內(nèi)的所有SQL都將被取消執(zhí)行。MySQL事務(wù)處理只支持InnoDB和BDB數(shù)據(jù)表類(lèi)型。
1事務(wù)的ACID原則
** 1(Atomicity)原子性**: 事務(wù)是最小的執(zhí)行單位,不允許分割。原子性確保動(dòng)作要么全部完成,要么完全不起作用;
2(Consistency)一致性: 執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致;
3(Isolation)隔離性: 并發(fā)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí),一個(gè)事務(wù)不被其他事務(wù)所干擾。
4(Durability)持久性: 一個(gè)事務(wù)被提交之后。對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變是持久的,即使數(shù)據(jù)庫(kù)發(fā)生故障。
1緩沖池(Buffer Pool)
Buffer Pool中包含了磁盤(pán)中部分?jǐn)?shù)據(jù)頁(yè)的映射。當(dāng)從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)時(shí),會(huì)先從Buffer Pool中讀取數(shù)據(jù),如果Buffer Pool中沒(méi)有,則從磁盤(pán)讀取后放入到Buffer Pool中。當(dāng)向數(shù)據(jù)庫(kù)寫(xiě)入數(shù)據(jù)時(shí),會(huì)先寫(xiě)入到Buffer Pool中,Buffer Pool中更新的數(shù)據(jù)會(huì)定期刷新到磁盤(pán)中(此過(guò)程稱(chēng)為刷臟)。
2日志緩沖區(qū)(Log Buffer)
當(dāng)在MySQL中對(duì)InnoDB表進(jìn)行更改時(shí),這些更改命令首先存儲(chǔ)在InnoDB日志緩沖區(qū)(Log Buffer)的內(nèi)存中,然后寫(xiě)入通常稱(chēng)為重做日志(redo logs)的InnoDB日志文件中。
3雙寫(xiě)機(jī)制緩存(DoubleWrite Buffer)
Doublewrite Buffer是共享表空間的物理文件的 buffer,其大小是2MB.是一個(gè)一分為二的2MB空間。
刷臟操作開(kāi)始之時(shí),先進(jìn)行臟頁(yè)**‘備份’**操作.將臟頁(yè)數(shù)據(jù)寫(xiě)入 Doublewrite Buffer.
將Doublewrite Buffer(順序IO)寫(xiě)入磁盤(pán)文件中(共享表空間) 進(jìn)行刷臟操作.
4回滾日志(Undo Log)
Undo Log記錄的是邏輯日志.記錄的是事務(wù)過(guò)程中每條數(shù)據(jù)的變化版本和情況.
在Innodb 磁盤(pán)架構(gòu)中Undo Log 默認(rèn)是共享表空間的物理文件的Buffer.
在事務(wù)異常中斷,或者主動(dòng)(Rollback)回滾的過(guò)程中 ,Innodb基于 Undo Log進(jìn)行數(shù)據(jù)撤銷(xiāo)回滾,保證數(shù)據(jù)回歸至事務(wù)開(kāi)始狀態(tài).
5重做日志(Redo Log)
Redo Log通常指的是物理日志,記錄的是數(shù)據(jù)頁(yè)的物理修改.并不記錄行記錄情況。(也就是只記錄要做哪些修改,并不記錄修改的完成情況) 當(dāng)數(shù)據(jù)庫(kù)宕機(jī)重啟的時(shí)候,會(huì)將重做日志中的內(nèi)容恢復(fù)到數(shù)據(jù)庫(kù)中。
1原子性
Innodb事務(wù)的原子性保證,包含事務(wù)的提交機(jī)制和事務(wù)的回滾機(jī)制.在Innodb引擎中事務(wù)的回滾機(jī)制是依托 回滾日志(Undo Log) 進(jìn)行回滾數(shù)據(jù),保證數(shù)據(jù)回歸至事務(wù)開(kāi)始狀態(tài).
2那么不同的隔離級(jí)別,隔離性是如何實(shí)現(xiàn)的,為什么不同事物間能夠互不干擾? 答案是 鎖 和 MVCC。
3持久性
基于事務(wù)的提交機(jī)制流程有可能出現(xiàn)三種場(chǎng)景.
1 數(shù)據(jù)刷臟正常.一切正常提交,Redo Log 循環(huán)記錄.數(shù)據(jù)成功落盤(pán).持久性得以保證
2數(shù)據(jù)刷臟的過(guò)程中出現(xiàn)的系統(tǒng)意外導(dǎo)致頁(yè)斷裂現(xiàn)象 (部分刷臟成功),針對(duì)頁(yè)斷裂情況,采用Double write機(jī)制進(jìn)行保證頁(yè)斷裂數(shù)據(jù)的恢復(fù).
3數(shù)據(jù)未出現(xiàn)頁(yè)斷裂現(xiàn)象,也沒(méi)有刷臟成功,MySQL通過(guò)Redo Log 進(jìn)行數(shù)據(jù)的持久化即可
4一致性
從數(shù)據(jù)庫(kù)層面,數(shù)據(jù)庫(kù)通過(guò)原子性、隔離性、持久性來(lái)保證一致性
2事務(wù)的隔離級(jí)別
Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級(jí)別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級(jí)別
臟讀: 指一個(gè)事務(wù)讀取了另外一個(gè)事務(wù)未提交的數(shù)據(jù)。
不可重復(fù)讀: 在一個(gè)事務(wù)內(nèi)讀取表中的某一行數(shù)據(jù),多次讀取結(jié)果不同
虛讀(幻讀): 是指在一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致。
2基本語(yǔ)法
-- 使用set語(yǔ)句來(lái)改變自動(dòng)提交模式
SET autocommit = 0; /*關(guān)閉*/
SET autocommit = 1; /*開(kāi)啟*/
-- 注意:
--- 1.MySQL中默認(rèn)是自動(dòng)提交
--- 2.使用事務(wù)時(shí)應(yīng)先關(guān)閉自動(dòng)提交
-- 開(kāi)始一個(gè)事務(wù),標(biāo)記事務(wù)的起始點(diǎn)
START TRANSACTION
-- 提交一個(gè)事務(wù)給數(shù)據(jù)庫(kù)
COMMIT
-- 將事務(wù)回滾,數(shù)據(jù)回到本次事務(wù)的初始狀態(tài)
ROLLBACK
-- 還原MySQL數(shù)據(jù)庫(kù)的自動(dòng)提交
SET autocommit =1;
-- 保存點(diǎn)
SAVEPOINT 保存點(diǎn)名稱(chēng) -- 設(shè)置一個(gè)事務(wù)保存點(diǎn)
ROLLBACK TO SAVEPOINT 保存點(diǎn)名稱(chēng) -- 回滾到保存點(diǎn)
RELEASE SAVEPOINT 保存點(diǎn)名稱(chēng) -- 刪除保存點(diǎn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
課堂測(cè)試題目
A在線(xiàn)買(mǎi)一款價(jià)格為500元商品,網(wǎng)上銀行轉(zhuǎn)賬.
A的銀行卡余額為2000,然后給商家B支付500.
商家B一開(kāi)始的銀行卡余額為10000
創(chuàng)建數(shù)據(jù)庫(kù)shop和創(chuàng)建表account并插入2條數(shù)據(jù)
*/
CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `shop`;
CREATE TABLE `account` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`cash` DECIMAL(9,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO account (`name`,`cash`)
VALUES('A',2000.00),('B',10000.00)
-- 轉(zhuǎn)賬實(shí)現(xiàn)
SET autocommit = 0; -- 關(guān)閉自動(dòng)提交
START TRANSACTION; -- 開(kāi)始一個(gè)事務(wù),標(biāo)記事務(wù)的起始點(diǎn)
UPDATE account SET cash=cash-500 WHERE `name`='A';
UPDATE account SET cash=cash+500 WHERE `name`='B';
COMMIT; -- 提交事務(wù)
# rollback;
SET autocommit = 1; -- 恢復(fù)自動(dòng)提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
3事務(wù)實(shí)現(xiàn)方式-MVCC
1什么是MVCC
MVCC是mysql的的多版本并發(fā)控制即multi-Version Concurrency Controller,mysql的innodb引擎支持MVVC。MVCC是為了實(shí)現(xiàn)事務(wù)的隔離性,通過(guò)版本號(hào),避免同一數(shù)據(jù)在不同事務(wù)間的競(jìng)爭(zhēng),你可以把它當(dāng)成基于多版本號(hào)的一種樂(lè)觀(guān)鎖。當(dāng)然,這種樂(lè)觀(guān)鎖只在事務(wù)級(jí)別為RR(可重復(fù)讀)和RC(讀提交)生效。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖,讀寫(xiě)不沖突,極大的增加了系統(tǒng)的并發(fā)性能。
2MVCC的實(shí)現(xiàn)機(jī)制
InnoDB在每行數(shù)據(jù)都增加兩個(gè)隱藏字段,一個(gè)記錄創(chuàng)建的版本號(hào),一個(gè)記錄刪除的版本號(hào)。
在多版本并發(fā)控制中,為了保證數(shù)據(jù)操作在多線(xiàn)程過(guò)程中,保證事務(wù)隔離的機(jī)制,降低鎖競(jìng)爭(zhēng)的壓力,保證較高的并發(fā)量。在每開(kāi)啟一個(gè)事務(wù)時(shí),會(huì)生成一個(gè)事務(wù)的版本號(hào),被操作的數(shù)據(jù)會(huì)生成一條新的數(shù)據(jù)行(臨時(shí)),但是在提交前對(duì)其他事務(wù)是不可見(jiàn)的;對(duì)于數(shù)據(jù)的更新(包括增刪改)操作成功,會(huì)將這個(gè)版本號(hào)更新到數(shù)據(jù)的行中;事務(wù)提交成功,新的版本號(hào)也就更新到了此數(shù)據(jù)行中。這樣保證了每個(gè)事務(wù)操作的數(shù)據(jù),都是互不影響的,也不存在鎖的問(wèn)題。
3MVCC下的CRUD
SELECT:
當(dāng)隔離級(jí)別是REPEATABLE READ時(shí)select操作,InnoDB每行數(shù)據(jù)來(lái)保證它符合兩個(gè)條件:
** 1 事務(wù)的版本號(hào) 大于等于 創(chuàng)建行版本號(hào)**
** 2 行數(shù)據(jù)的刪除版本 未定義 或者大于 事務(wù)版本號(hào)**
【行創(chuàng)建版本號(hào) 事務(wù)版本號(hào) 行刪除版本號(hào)】
INSERT:
InnoDB為這個(gè)新行 記錄 當(dāng)前的系統(tǒng)版本號(hào)。
DELETE:
InnoDB將當(dāng)前的系統(tǒng)版本號(hào) 設(shè)置為 這一行的刪除版本號(hào)。
UPDATE:
InnoDB會(huì)寫(xiě)一個(gè)這行數(shù)據(jù)的新拷貝,這個(gè)拷貝的版本為 當(dāng)前的系統(tǒng)版本號(hào)。它同時(shí)也會(huì)將這個(gè)版本號(hào) 寫(xiě)到 舊行的刪除版本里。
————————————————
版權(quán)聲明:本文為CSDN博主「@Autowire」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:
mysql是怎樣運(yùn)行的從根兒上理解mysql電子書(shū)
《MySQL是怎樣運(yùn)行的:從根兒上理解 MySQL》采用詼諧幽默的表達(dá)方式,對(duì)MySQL的底層運(yùn)行原理進(jìn)行了介紹,內(nèi)容涵蓋了使用MySQL的同學(xué)在求職面試和工作中常見(jiàn)的一些核心概念??傆?jì)22 章,劃分為4個(gè)部分。第1部分介紹了MySQL入門(mén)的一些知識(shí),比如MySQL的服務(wù)器程序和客戶(hù)端程序有哪些、MySQL的啟動(dòng)選項(xiàng)和系統(tǒng)變量,以及使用的字符集等。第2部分是本書(shū)后續(xù)章節(jié)的基礎(chǔ),介紹了MySQL的一些基礎(chǔ)知識(shí),比如記錄、頁(yè)面、索引、表空間的結(jié)構(gòu)和用法等。第3部分則與大家在工作中經(jīng)常遇到的查詢(xún)優(yōu)化問(wèn)題緊密相關(guān),介紹了單表查詢(xún)、連接查詢(xún)的執(zhí)行原理,MySQL基于成本和規(guī)則的優(yōu)化具體指什么,并詳細(xì)分析了Explain語(yǔ)句的執(zhí)行結(jié)果。第4部分則是與MySQL中的事務(wù)和鎖相關(guān),介紹了事務(wù)概念的來(lái)源,MySQL是如何實(shí)現(xiàn)事務(wù)的,包括redo日志、undo日志、MVCC、各種鎖的細(xì)節(jié)等。
盡管《MySQL是怎樣運(yùn)行的:從根兒上理解 MySQL》在寫(xiě)作時(shí)參考的MySQL源代碼版本是5.7.22,但是大部分內(nèi)容與具體的版本號(hào)并沒(méi)有多大關(guān)系。無(wú)論是很早之前就已身居MySQL專(zhuān)家的人員,還是希望進(jìn)一步提升技能的DBA,甚至是三五年后才會(huì)入行的“萌新”,本書(shū)都是他們徹底了解MySQL運(yùn)行原理的優(yōu)秀書(shū)
什么是mysql的事務(wù)和實(shí)現(xiàn)
msql的一個(gè)事務(wù)的回歸測(cè)試,可以自測(cè)一下,了解下事務(wù)。
舉個(gè)例子:小明和小飛兩個(gè)人現(xiàn)在手里各有¥100,突然小飛腦袋出問(wèn)題了說(shuō)給小明¥50,現(xiàn)在他們手里的錢(qián)就是(小明:¥150,小飛:¥50);這樣同步就是一個(gè)事務(wù)的完成,下面是demo
/*
事務(wù) ACID
原子性 Atomic
一致性 Consistency
隔離性 Isolation
持久性 Durability
*/
var?mysql?=?require('mysql');
var?connection?=?mysql.createConnection({
host:'localhost',
user:'root',
password:'',
database:'yudi'
});
connection.connect();
//開(kāi)始一個(gè)事務(wù)
connection.beginTransaction(function(err){
if(err)?throw?err;
connection.query('update?account1?set?mny=0?where?id=1',function(err,results){
if(err){
connection.rollback(function(){
throw?err;
})
throw?err;
}
connection.query('update?account2?set?mny=200?where?id=1',function(err,results){
if(err){
//回滾一個(gè)事物
connection.rollback(function(){
throw?err;
})
throw?err;
}
//提交一個(gè)事物
connection.commit(function(err){
if(err){
connection.rollback(function(){
throw?err;
})
throw?err;
}
console.log('success');
});
});
});
})
關(guān)系型數(shù)據(jù)庫(kù)事務(wù)的ACID特性與實(shí)現(xiàn)
ACID 是為保證事務(wù)(transaction)是正確可靠的,所必須具備的四個(gè)特性:
以 A 給 B 轉(zhuǎn)賬100元為例:
MySQL事務(wù)是由 InnoDB 存儲(chǔ)引擎實(shí)現(xiàn)的。
可以用如下的命令顯式的開(kāi)啟事務(wù):
另外,在自動(dòng)提交(autocommit)模式下,我們執(zhí)行的每一條 SQL 語(yǔ)句都是一條獨(dú)立的事務(wù);如果關(guān)閉了自動(dòng)提交(autocommit)模式,則所有的 SQL 語(yǔ)句都在一個(gè)事務(wù)中,直到執(zhí)行了 commit 或 rollback,該事務(wù)結(jié)束,同時(shí)開(kāi)始了另外一個(gè)事務(wù)。
MySQL 事務(wù)的 ACID 特性靠如下機(jī)制實(shí)現(xiàn):
Go 語(yǔ)言的 Gorm 提供了對(duì)于事務(wù)操作的支持:
此外,還有嵌套事務(wù)以及手動(dòng)事務(wù)等操作,可以參考中文文檔: learnku.com/docs/gorm/v…
@Transactional 注解必須添加在public方法上,private、protected方法上是無(wú)效的。
一般情況下,推薦將@Transactional 注解加在方法上,因?yàn)锧Transactional直接加在類(lèi)或者接口上,@Transactional注解會(huì)對(duì)類(lèi)或者接口里面所有的public方法都有效,會(huì)影響性能。
網(wǎng)站標(biāo)題:mysql事務(wù)怎么實(shí)現(xiàn)的 mysql行鎖怎么實(shí)現(xiàn)的
URL標(biāo)題:http://www.dlmjj.cn/article/doghoji.html