function func($val,$id) {
創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè)|成都網(wǎng)站維護(hù)|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋雨棚定制等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身策劃品質(zhì)網(wǎng)站。
$sql="update table set a=? where id=?";
$pre=$this-pdo-prepare($sql);
$this-pdo-beginTransaction();//開啟事務(wù)
$bo=$pre-execute(array($val,$id));
if($bo){
//…執(zhí)行代碼……
$this-pdo-commit();//提交事務(wù)
return true;
}else{
//…執(zhí)行代碼……
$this-pdo-rollBack();//回滾事務(wù)
return false;
}
}
id 自增,name 為字符串類型
table 依然為空,開啟事務(wù)后在沒有commit的情況下,是沒有修改 table 的。
這里將事務(wù) b 直接提交
由于事物 b 提交了,插入了一行數(shù)據(jù),id 為 2,所以這里生成 id 是在插入的時(shí)候。
這個(gè)時(shí)候開始提交事物a
事務(wù) a 和 b 都提交成功,上一個(gè)事務(wù)a的插入的數(shù)據(jù)項(xiàng)也出現(xiàn)了。
由于事物 c 回滾,事物 d 提交成功,所以 table 中確實(shí)是少了一行數(shù)據(jù)。
自增 id,是在插入的時(shí)候就已經(jīng)生成了,事務(wù)并不影響 id 的自增。
如果事務(wù)回滾,table 對應(yīng)的數(shù)據(jù)行就會(huì)缺失,id 也會(huì)缺失,自增 id 和事務(wù)是獨(dú)立的,互不影響。
回答的有點(diǎn)多請耐心看完。
希望能幫助你還請及時(shí)采納謝謝
1事務(wù)的原理
事務(wù)就是將一組SQL語句放在同一批次內(nèi)去執(zhí)行,如果一個(gè)SQL語句出錯(cuò),則該批次內(nèi)的所有SQL都將被取消執(zhí)行。MySQL事務(wù)處理只支持InnoDB和BDB數(shù)據(jù)表類型。
1事務(wù)的ACID原則
** 1(Atomicity)原子性**: 事務(wù)是最小的執(zhí)行單位,不允許分割。原子性確保動(dòng)作要么全部完成,要么完全不起作用;
2(Consistency)一致性: 執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致;
3(Isolation)隔離性: 并發(fā)訪問數(shù)據(jù)庫時(shí),一個(gè)事務(wù)不被其他事務(wù)所干擾。
4(Durability)持久性: 一個(gè)事務(wù)被提交之后。對數(shù)據(jù)庫中數(shù)據(jù)的改變是持久的,即使數(shù)據(jù)庫發(fā)生故障。
1緩沖池(Buffer Pool)
Buffer Pool中包含了磁盤中部分?jǐn)?shù)據(jù)頁的映射。當(dāng)從數(shù)據(jù)庫讀取數(shù)據(jù)時(shí),會(huì)先從Buffer Pool中讀取數(shù)據(jù),如果Buffer Pool中沒有,則從磁盤讀取后放入到Buffer Pool中。當(dāng)向數(shù)據(jù)庫寫入數(shù)據(jù)時(shí),會(huì)先寫入到Buffer Pool中,Buffer Pool中更新的數(shù)據(jù)會(huì)定期刷新到磁盤中(此過程稱為刷臟)。
2日志緩沖區(qū)(Log Buffer)
當(dāng)在MySQL中對InnoDB表進(jìn)行更改時(shí),這些更改命令首先存儲(chǔ)在InnoDB日志緩沖區(qū)(Log Buffer)的內(nèi)存中,然后寫入通常稱為重做日志(redo logs)的InnoDB日志文件中。
3雙寫機(jī)制緩存(DoubleWrite Buffer)
Doublewrite Buffer是共享表空間的物理文件的 buffer,其大小是2MB.是一個(gè)一分為二的2MB空間。
刷臟操作開始之時(shí),先進(jìn)行臟頁**‘備份’**操作.將臟頁數(shù)據(jù)寫入 Doublewrite Buffer.
將Doublewrite Buffer(順序IO)寫入磁盤文件中(共享表空間) 進(jìn)行刷臟操作.
4回滾日志(Undo Log)
Undo Log記錄的是邏輯日志.記錄的是事務(wù)過程中每條數(shù)據(jù)的變化版本和情況.
在Innodb 磁盤架構(gòu)中Undo Log 默認(rèn)是共享表空間的物理文件的Buffer.
在事務(wù)異常中斷,或者主動(dòng)(Rollback)回滾的過程中 ,Innodb基于 Undo Log進(jìn)行數(shù)據(jù)撤銷回滾,保證數(shù)據(jù)回歸至事務(wù)開始狀態(tài).
5重做日志(Redo Log)
Redo Log通常指的是物理日志,記錄的是數(shù)據(jù)頁的物理修改.并不記錄行記錄情況。(也就是只記錄要做哪些修改,并不記錄修改的完成情況) 當(dāng)數(shù)據(jù)庫宕機(jī)重啟的時(shí)候,會(huì)將重做日志中的內(nèi)容恢復(fù)到數(shù)據(jù)庫中。
1原子性
Innodb事務(wù)的原子性保證,包含事務(wù)的提交機(jī)制和事務(wù)的回滾機(jī)制.在Innodb引擎中事務(wù)的回滾機(jī)制是依托 回滾日志(Undo Log) 進(jìn)行回滾數(shù)據(jù),保證數(shù)據(jù)回歸至事務(wù)開始狀態(tài).
2那么不同的隔離級別,隔離性是如何實(shí)現(xiàn)的,為什么不同事物間能夠互不干擾? 答案是 鎖 和 MVCC。
3持久性
基于事務(wù)的提交機(jī)制流程有可能出現(xiàn)三種場景.
1 數(shù)據(jù)刷臟正常.一切正常提交,Redo Log 循環(huán)記錄.數(shù)據(jù)成功落盤.持久性得以保證
2數(shù)據(jù)刷臟的過程中出現(xiàn)的系統(tǒng)意外導(dǎo)致頁斷裂現(xiàn)象 (部分刷臟成功),針對頁斷裂情況,采用Double write機(jī)制進(jìn)行保證頁斷裂數(shù)據(jù)的恢復(fù).
3數(shù)據(jù)未出現(xiàn)頁斷裂現(xiàn)象,也沒有刷臟成功,MySQL通過Redo Log 進(jìn)行數(shù)據(jù)的持久化即可
4一致性
從數(shù)據(jù)庫層面,數(shù)據(jù)庫通過原子性、隔離性、持久性來保證一致性
2事務(wù)的隔離級別
Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級別
臟讀: 指一個(gè)事務(wù)讀取了另外一個(gè)事務(wù)未提交的數(shù)據(jù)。
不可重復(fù)讀: 在一個(gè)事務(wù)內(nèi)讀取表中的某一行數(shù)據(jù),多次讀取結(jié)果不同
虛讀(幻讀): 是指在一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致。
2基本語法
-- 使用set語句來改變自動(dòng)提交模式
SET autocommit = 0; /*關(guān)閉*/
SET autocommit = 1; /*開啟*/
-- 注意:
--- 1.MySQL中默認(rèn)是自動(dòng)提交
--- 2.使用事務(wù)時(shí)應(yīng)先關(guān)閉自動(dòng)提交
-- 開始一個(gè)事務(wù),標(biāo)記事務(wù)的起始點(diǎn)
START TRANSACTION
-- 提交一個(gè)事務(wù)給數(shù)據(jù)庫
COMMIT
-- 將事務(wù)回滾,數(shù)據(jù)回到本次事務(wù)的初始狀態(tài)
ROLLBACK
-- 還原MySQL數(shù)據(jù)庫的自動(dòng)提交
SET autocommit =1;
-- 保存點(diǎn)
SAVEPOINT 保存點(diǎn)名稱 -- 設(shè)置一個(gè)事務(wù)保存點(diǎn)
ROLLBACK TO SAVEPOINT 保存點(diǎn)名稱 -- 回滾到保存點(diǎn)
RELEASE SAVEPOINT 保存點(diǎn)名稱 -- 刪除保存點(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
/*
課堂測試題目
A在線買一款價(jià)格為500元商品,網(wǎng)上銀行轉(zhuǎn)賬.
A的銀行卡余額為2000,然后給商家B支付500.
商家B一開始的銀行卡余額為10000
創(chuàng)建數(shù)據(jù)庫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; -- 開始一個(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ù)的隔離性,通過版本號,避免同一數(shù)據(jù)在不同事務(wù)間的競爭,你可以把它當(dāng)成基于多版本號的一種樂觀鎖。當(dāng)然,這種樂觀鎖只在事務(wù)級別為RR(可重復(fù)讀)和RC(讀提交)生效。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖,讀寫不沖突,極大的增加了系統(tǒng)的并發(fā)性能。
2MVCC的實(shí)現(xiàn)機(jī)制
InnoDB在每行數(shù)據(jù)都增加兩個(gè)隱藏字段,一個(gè)記錄創(chuàng)建的版本號,一個(gè)記錄刪除的版本號。
在多版本并發(fā)控制中,為了保證數(shù)據(jù)操作在多線程過程中,保證事務(wù)隔離的機(jī)制,降低鎖競爭的壓力,保證較高的并發(fā)量。在每開啟一個(gè)事務(wù)時(shí),會(huì)生成一個(gè)事務(wù)的版本號,被操作的數(shù)據(jù)會(huì)生成一條新的數(shù)據(jù)行(臨時(shí)),但是在提交前對其他事務(wù)是不可見的;對于數(shù)據(jù)的更新(包括增刪改)操作成功,會(huì)將這個(gè)版本號更新到數(shù)據(jù)的行中;事務(wù)提交成功,新的版本號也就更新到了此數(shù)據(jù)行中。這樣保證了每個(gè)事務(wù)操作的數(shù)據(jù),都是互不影響的,也不存在鎖的問題。
3MVCC下的CRUD
SELECT:
當(dāng)隔離級別是REPEATABLE READ時(shí)select操作,InnoDB每行數(shù)據(jù)來保證它符合兩個(gè)條件:
** 1 事務(wù)的版本號 大于等于 創(chuàng)建行版本號**
** 2 行數(shù)據(jù)的刪除版本 未定義 或者大于 事務(wù)版本號**
【行創(chuàng)建版本號 事務(wù)版本號 行刪除版本號】
INSERT:
InnoDB為這個(gè)新行 記錄 當(dāng)前的系統(tǒng)版本號。
DELETE:
InnoDB將當(dāng)前的系統(tǒng)版本號 設(shè)置為 這一行的刪除版本號。
UPDATE:
InnoDB會(huì)寫一個(gè)這行數(shù)據(jù)的新拷貝,這個(gè)拷貝的版本為 當(dāng)前的系統(tǒng)版本號。它同時(shí)也會(huì)將這個(gè)版本號 寫到 舊行的刪除版本里。
————————————————
版權(quán)聲明:本文為CSDN博主「@Autowire」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接: