本文目錄一覽:
- 1、Mysql數據庫中,事務是指什麼?如何使用該功能?
- 2、談談你對 mysql 事務的認識 我是php初學者不懂這個 想請教大神教我
- 3、數據庫詳解之事務
- 4、數據庫的事務機制是什麼
- 5、什麼叫mysql事務?
Mysql數據庫中,事務是指什麼?如何使用該功能?
MySQL 事務
什麼是事務?
MySQL 事務主要用於處理操作量大,複雜度高的數據。比如說,在人員管理系統中,你刪除一個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務!
在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
事務用來管理 insert,update,delete 語句
一般來說,事務是必須滿足4個條件(ACID):原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。
原子性:一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
一致性:在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續數據庫可以自發性地完成預定的工作。
隔離性:數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
持久性:事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。
在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。
from 樹懶學堂 – 一站式數據知識平台
談談你對 mysql 事務的認識 我是php初學者不懂這個 想請教大神教我
先簡單介紹一下事務吧!事務是DBMS得執行單位。它由有限得數據庫操作序列組成得。但不是任意得數據庫操作序列都能成為事務。一般來說,事務是必須滿足4個條件(ACID)
原子性(Autmic):事務在執行性,要做到“要麼不做,要麼全做!”,就是說不允許事務部分得執行。即使因為故障而使事務不能完成,在rollback時也要消除對數據庫得影響!
一致性(Consistency):事務得操作應該使使數據庫從一個一致狀態轉變倒另一個一致得狀態!就拿網上購物來說吧,你只有即讓商品出庫,又讓商品進入顧客得購物籃才能構成事務!
隔離性(Isolation):如果多個事務並發執行,應象各個事務獨立執行一樣!
持久性(Durability):一個成功執行得事務對數據庫得作用是持久得,即使數據庫應故障出錯,也應該能夠恢復!
MYSQL的事務處理主要有兩種方法。
1、用begin,rollback,commit來實現
begin
開始一個事務
rollback 事務回滾
commit 事務確認
2、直接用set來改變mysql的自動提交模式
MYSQL默認是自動提交的,也就是你提交一個QUERY,它就直接執行!我們可以通過
set autocommit=0
禁止自動提交
set autocommit=1 開啟自動提交
來實現事務的處理。
但注意當你用 set
autocommit=0
的時候,你以後所有的SQL都將做為事務處理,直到你用commit確認或rollback結束,注意當你結束這個事務的同時也開啟了個新的事務!按第一種方法只將當前的作為一個事務!
個人推薦使用第一種方法!
MYSQL中只有INNODB和BDB類型的數據表才能支持事務處理!其他的類型是不支持的!(切記!)
下次有空說下MYSQL的數據表的鎖定和解鎖!
MYSQL5.0 WINXP下測試通過~ ^_^
mysql use test;
Database
changed
mysql CREATE TABLE `dbtest`(
– id int(4)
– ) TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05
sec)
mysql select * from dbtest
– ;
Empty set (0.01
sec)
mysql begin;
Query OK, 0 rows affected (0.00
sec)
mysql insert into dbtest value(5);
Query OK, 1 row affected
(0.00 sec)
mysql insert into dbtest value(6);
Query OK, 1 row
affected (0.00 sec)
mysql commit;
Query OK, 0 rows affected (0.00
sec)
mysql select * from dbtest;
+——+
| id
|
+——+
| 5 |
| 6 |
+——+
2 rows in set (0.00
sec)
mysql begin;
Query OK, 0 rows affected (0.00
sec)
mysql insert into dbtest values(7);
Query OK, 1 row affected
(0.00 sec)
mysql rollback;
Query OK, 0 rows affected (0.00
sec)
mysql select * from dbtest;
+——+
| id
|
+——+
| 5 |
| 6 |
+——+
2 rows in set (0.00
sec)
mysql
*******************************************************************************************************************
[PHP]
function
Tran( $sql ) {
$judge = 1;
mysql_query(‘begin’);
foreach ($sql as $v) {
if
( !mysql_query($v) ) {
$judge =
0;
}
}
if ($judge == 0)
{
mysql_query(‘rollback’);
return
false;
}
elseif ($judge == 1) {
mysql_query(‘commit’);
return true;
}
}
[/PHP]
************************************************
?php
$handler=mysql_connect(“localhost”,”root”,””);
mysql_select_db(“task”);
mysql_query(“SET
AUTOCOMMIT=0″);//設置為不自動提交,因為MYSQL默認立即執行
mysql_query(“BEGIN”);//開始事務定義
if(!mysql_query(“insert
into trans (id)
values(‘2’)”))
{
mysql_query(“ROOLBACK”);//判斷當執行失敗時回滾
}
if(!mysql_query(“insert
into trans (id)
values(‘4’)”))
{
mysql_query(“ROOLBACK”);//判斷執行失敗回滾
}
mysql_query(“COMMIT”);//執行事務
mysql_close($handler);
?
引自:
數據庫詳解之事務
究竟什麼是數據庫的事務,為什麼數據庫需要支持事務,為了實現數據庫事務各種數據庫的是如何設計的。還是只談理解,歡迎大家來討論。
1. 數據庫事務是什麼
事務的定義,已經有太多文章寫過,我就不重複了。我理解的事務就是用來保證數據操作符合業務邏輯要求而實現的一系列功能。換句話說,如果數據庫不支持事務,上面業務系統的程序員就需要自己寫代碼保證相關數據處理邏輯的正確性。而數據庫事務就是把一系列保證數據庫處理邏輯正確性的通用功能在數據庫內實現,並且盡量提高效率。
舉個例子,數據庫最開始普及就是在金融業,銀行的存取款場景就是一個最典型的OLTP數據庫場景,而事務就是設計用來保證類似場景的業務邏輯正確性的。
![事務的四個基本特性]()
**原子性**,如果你要給家人轉賬,必須在你的賬戶里扣掉100塊,在家人賬戶里加上100塊,這兩筆操作需要一起完成,業務邏輯才是正確的。但是程序在做修改的時,肯定會有先後順序,試想一下程序扣了你的錢,這個時候程序崩潰了,家人賬戶的錢沒有加上。那這100塊是不是消失了?你是不是要發瘋?那麼,就把這兩筆操作放進一個事務里,通過原子性保證,這兩筆操作要麼都成功,要麼都失敗。這樣才能保證業務邏輯的正確性。
**一致性**,有很多文章講過一致性,但是很多人會把一致性跟原子性混在一起說。事務的一致性指的是指每一個事務必須保證執行之後所有庫內的規則依舊成立。比如內外鍵,constraint,觸發器等。舉例來說,你在儲蓄卡里有100元,理財賬戶里有100元,基金賬戶有100元,那麼你在資產總和里會看到300元,這個300元必須是其他三個賬戶餘額加在一起得到的。你在給家人轉帳100元是從儲蓄卡里轉出去了100元,那麼在數據庫上可以通過創建觸發器的方式,當儲蓄卡餘額賬戶減100元的同時,把資產總和也同步減去100,不然的話,就會出現邏輯上的錯誤,因為你已經轉走了100塊儲蓄卡餘額,實際資產總和應該是200,如果還是300,數據庫狀態就不一致了。所以實現事務的時候,必須要保證相關聯的觸發器以及其他所有的內部規則都執行成功,事務才能算執行成功。如果在減去資產總時出錯,那麼這筆轉帳交易也不能成功。因為這樣數據庫就會進入不一致的狀態。
那麼這裡跟原子性的區別到底在哪裡呢?原子性是指個多個用戶指令之間必須作為一個整體完成或失敗,而一致性更多是數據庫內的相關數據規則必須同時完成或失敗。
**持久性**,最容易理解的一個,事務只要提交了,那麼對數據庫的修改就會保存下來不會丟了。簡單來說,只要提交了,數據庫就算崩潰了,重啟之後你剛存的100塊依然在你的賬戶里。
**隔離性**,每個事務相對於其他的事務是有一定獨立性的,不能互相影響。因為數據庫需要支持並發的操作來提高效率。在並發操作時,一定要通過操作之間的隔離來保證業務邏輯的正確性。比如,你轉帳100塊給家人,一系列操作的最後一步可能是輸入驗證碼,這個時候轉帳還沒有完成,但是在數據庫里你的賬戶對應的記錄中已經減去100塊,家人賬戶也加了100塊,就等着驗證碼輸入以後,事務提交,完成操作。那麼,這個時候,家人通過手機銀行能夠查到這100塊么?你的答案可能是不能,因為這樣才符合業務邏輯,因為你的轉帳操作還沒有提交,事務還沒有完成。那麼數據庫就應該保證這兩個並發操作之間具有一定的隔離性。
那麼到底應該隔離到什麼程度呢?隔離性又分為4個等級:由低到高依次為Read uncommitted(讀未提交)、Read committed(讀提交)、Repeatable read(可重複讀取)、Serializable(序列化),這四個級別可以逐個解決臟讀、不可重複讀、幻象讀這幾類問題。這些東西是什麼意思?請有興趣的小夥伴自行百度,很多文章都寫的很清楚。
那麼怎麼理解不同的隔離等級呢,首先要理解並發操作,並發操作就是指有不同的用戶同時對一個數據進行讀、寫操作,那麼在這個過程中,每個用戶應該看到什麼數據才能保證業務邏輯的正確性呢? 如果是前面存取款的場景,我必須看到的是已經存進來的錢,也就是必須是已經提交的事務。而12306刷火車票呢,你可以看到有10張余票,但是在下單的時候告訴你票賣完了,因為同時有10個用戶把票買掉了,你需要重新刷余票,這個也是可以接受的,也就是說我可以讀到一些虛假的余票,這樣在業務上也沒有什麼問題。那麼在設計這兩個不同系統時,就可以選擇不同的事務隔離級別來實現不同的並發效果。不同的隔離等級就是要在系統的並發性和數據邏輯的嚴謹性之間做出的平衡。
2. 數據庫如何實現事務
數據庫實現事務會有多種不同的方式,但基本的原理類似,比如都需要對事務進行統一的編號處理,都需要記錄事務的狀態(是成功了還是失敗了),都需要在數據存儲的層面對事務進行支持,以明確哪些數據是被哪些事務、插入、修改和刪除的。同時還會記錄事務日誌等,對事務進行系統化的管理以實現數據的原子性,一致性和持久性。
要實現事務的隔離性,最基礎的就是通過加鎖機制把並發操作適當的串行化來保證數據操作的正確邏輯。但是為了要保證系統具有良好的並發性能,必須要在實現事務隔離性時需要找到合理的平衡點。大部分數據庫(包括Oracle,MySQL,Postgres在內)在做並發控制的時候都會採用MVCC(多版本並發控制)的機制來保證系統具有較高的並發性,不同數據庫實現MVCC的具體方案也不盡相同,但其基本原理類似。
3. MVCC實現原理
所謂MVCC,就是數據庫中的同一查詢根據相關事務執行的先後順序以及隔離級別的不同,可能會存在不同版本的結果,通過這樣的手段來保證大部分查詢操作不會被修改操作阻塞並保證數據邏輯的正確性。也就是數據庫通過保存多個版本的數據( 歷史 數據)來提高系統的並發查詢能力。簡單來說就是用存儲空間來交換並發能力。下面以Postgres為例介紹一下MVCC的一種實現方式幫助大家理解這個重要的數據庫概念。通過下面的圖來解釋Posrgres里最基本的數據可見性是如何實現多版本控制的。
![在這裡插入圖片描述]()
首先,Postgres里的每一個事務都有編號,這裡可以簡單理解為時間順序編號,編號越大的事務發生越晚。然後,數據庫里的每一行記錄都會保存創建這條記錄的事務號(Cre),也會在記錄刪除時保存刪除這條記錄的事務號(Exp),換句話說,只要Exp這裡一列里記錄了事務編號,就說明這條記錄被刪除了。那麼一個事務應該能看見那些記錄呢?Postgres里每一個事務都會保存一個當前系統的事務快照(Snapshot),這個快照里會保存事務創建時當前系統的最高(最晚)事務編號,以及目前還在進行中的事務編號。那麼如上圖所示的一個事務的快照里最高事務編號為100,目前正在進行的事務有25,50和75。那麼對應左邊數據記錄,這6行數據的可見性就如同標註的一般:
第一行,Cre 30,沒有刪除,在100這個時間點,應該能看到。
第二行,Cre 50,沒有刪除,但是50這個事務還沒有提交,正在進行中,所以看不見。
第三行,Cre 110,沒有刪除,但是100這個時間點110事務還沒有發生,所以看不見。
第四行,Cre 30,Exp 80,在80的時候數據被刪掉了,所以看不見。
第五行,Cre 30,Exp 75,在30的時候被創建,75時候被刪掉了,但是75這個事務在100的時候還沒有提交,所以這條記錄在100的時候還沒有刪掉,所以看得見。
第六行,Cre30,Exp 110,在30的時被創建,110時候被刪掉,但是在100時候,110還沒有發生,所以看得見。
綜上,就是這個事務對這六條記錄的可見性,也就是一個數據版本。那麼大家可以看一下如果另一個事務的快照里存的是最高事務編號為110,正在進行的事務為50,那麼它能看到的數據應該是哪幾行呢?同時大家也看到,Postgres里刪除一行數據其實就是在這一行的Exp這個列記錄一個刪除事務的編號,相當於做了一個刪除標記,而數據沒有真正被刪除,因此Postgres數據庫需要定期做數據清理操作(Vacuum)。Pstgres的在現實場景里會比這裡介紹的要複雜,因為我們這裡假定所有的事務最終都是正確提交了,如果存在某些事務沒有提交的情況,那麼可見性就會更加複雜,這裡不再展開了。
數據庫事務是基本的數據庫概念,之前已經有很多很好文章做過介紹,這裡希望能把自己的理解用比較通俗的描述分享給大家,歡迎來討論交流。
數據庫的事務機制是什麼
回答的有點多請耐心看完。
希望能幫助你還請及時採納謝謝
1事務的原理
事務就是將一組SQL語句放在同一批次內去執行,如果一個SQL語句出錯,則該批次內的所有SQL都將被取消執行。MySQL事務處理只支持InnoDB和BDB數據表類型。
1事務的ACID原則
** 1(Atomicity)原子性**: 事務是最小的執行單位,不允許分割。原子性確保動作要麼全部完成,要麼完全不起作用;
2(Consistency)一致性: 執行事務前後,數據保持一致;
3(Isolation)隔離性: 並發訪問數據庫時,一個事務不被其他事務所干擾。
4(Durability)持久性: 一個事務被提交之後。對數據庫中數據的改變是持久的,即使數據庫發生故障。
1緩衝池(Buffer Pool)
Buffer Pool中包含了磁盤中部分數據頁的映射。當從數據庫讀取數據時,會先從Buffer Pool中讀取數據,如果Buffer Pool中沒有,則從磁盤讀取後放入到Buffer Pool中。當向數據庫寫入數據時,會先寫入到Buffer Pool中,Buffer Pool中更新的數據會定期刷新到磁盤中(此過程稱為刷臟)。
2日誌緩衝區(Log Buffer)
當在MySQL中對InnoDB表進行更改時,這些更改命令首先存儲在InnoDB日誌緩衝區(Log Buffer)的內存中,然後寫入通常稱為重做日誌(redo logs)的InnoDB日誌文件中。
3雙寫機制緩存(DoubleWrite Buffer)
Doublewrite Buffer是共享表空間的物理文件的 buffer,其大小是2MB.是一個一分為二的2MB空間。
刷臟操作開始之時,先進行臟頁**‘備份’**操作.將臟頁數據寫入 Doublewrite Buffer.
將Doublewrite Buffer(順序IO)寫入磁盤文件中(共享表空間) 進行刷臟操作.
4回滾日誌(Undo Log)
Undo Log記錄的是邏輯日誌.記錄的是事務過程中每條數據的變化版本和情況.
在Innodb 磁盤架構中Undo Log 默認是共享表空間的物理文件的Buffer.
在事務異常中斷,或者主動(Rollback)回滾的過程中 ,Innodb基於 Undo Log進行數據撤銷回滾,保證數據回歸至事務開始狀態.
5重做日誌(Redo Log)
Redo Log通常指的是物理日誌,記錄的是數據頁的物理修改.並不記錄行記錄情況。(也就是只記錄要做哪些修改,並不記錄修改的完成情況) 當數據庫宕機重啟的時候,會將重做日誌中的內容恢復到數據庫中。
1原子性
Innodb事務的原子性保證,包含事務的提交機制和事務的回滾機制.在Innodb引擎中事務的回滾機制是依託 回滾日誌(Undo Log) 進行回滾數據,保證數據回歸至事務開始狀態.
2那麼不同的隔離級別,隔離性是如何實現的,為什麼不同事物間能夠互不干擾? 答案是 鎖 和 MVCC。
3持久性
基於事務的提交機制流程有可能出現三種場景.
1 數據刷臟正常.一切正常提交,Redo Log 循環記錄.數據成功落盤.持久性得以保證
2數據刷髒的過程中出現的系統意外導致頁斷裂現象 (部分刷臟成功),針對頁斷裂情況,採用Double write機制進行保證頁斷裂數據的恢復.
3數據未出現頁斷裂現象,也沒有刷臟成功,MySQL通過Redo Log 進行數據的持久化即可
4一致性
從數據庫層面,數據庫通過原子性、隔離性、持久性來保證一致性
2事務的隔離級別
Mysql 默認採用的 REPEATABLE_READ隔離級別 Oracle 默認採用的 READ_COMMITTED隔離級別
臟讀: 指一個事務讀取了另外一個事務未提交的數據。
不可重複讀: 在一個事務內讀取表中的某一行數據,多次讀取結果不同
虛讀(幻讀): 是指在一個事務內讀取到了別的事務插入的數據,導致前後讀取不一致。
2基本語法
— 使用set語句來改變自動提交模式
SET autocommit = 0; /*關閉*/
SET autocommit = 1; /*開啟*/
— 注意:
— 1.MySQL中默認是自動提交
— 2.使用事務時應先關閉自動提交
— 開始一個事務,標記事務的起始點
START TRANSACTION
— 提交一個事務給數據庫
COMMIT
— 將事務回滾,數據回到本次事務的初始狀態
ROLLBACK
— 還原MySQL數據庫的自動提交
SET autocommit =1;
— 保存點
SAVEPOINT 保存點名稱 — 設置一個事務保存點
ROLLBACK TO SAVEPOINT 保存點名稱 — 回滾到保存點
RELEASE SAVEPOINT 保存點名稱 — 刪除保存點
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在線買一款價格為500元商品,網上銀行轉賬.
A的銀行卡餘額為2000,然後給商家B支付500.
商家B一開始的銀行卡餘額為10000
創建數據庫shop和創建表account並插入2條數據
*/
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)
— 轉賬實現
SET autocommit = 0; — 關閉自動提交
START TRANSACTION; — 開始一個事務,標記事務的起始點
UPDATE account SET cash=cash-500 WHERE `name`=’A’;
UPDATE account SET cash=cash+500 WHERE `name`=’B’;
COMMIT; — 提交事務
# rollback;
SET autocommit = 1; — 恢復自動提交
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事務實現方式-MVCC
1什麼是MVCC
MVCC是mysql的的多版本並發控制即multi-Version Concurrency Controller,mysql的innodb引擎支持MVVC。MVCC是為了實現事務的隔離性,通過版本號,避免同一數據在不同事務間的競爭,你可以把它當成基於多版本號的一種樂觀鎖。當然,這種樂觀鎖只在事務級別為RR(可重複讀)和RC(讀提交)生效。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖,讀寫不衝突,極大的增加了系統的並發性能。
2MVCC的實現機制
InnoDB在每行數據都增加兩個隱藏字段,一個記錄創建的版本號,一個記錄刪除的版本號。
在多版本並發控制中,為了保證數據操作在多線程過程中,保證事務隔離的機制,降低鎖競爭的壓力,保證較高的並發量。在每開啟一個事務時,會生成一個事務的版本號,被操作的數據會生成一條新的數據行(臨時),但是在提交前對其他事務是不可見的;對於數據的更新(包括增刪改)操作成功,會將這個版本號更新到數據的行中;事務提交成功,新的版本號也就更新到了此數據行中。這樣保證了每個事務操作的數據,都是互不影響的,也不存在鎖的問題。
3MVCC下的CRUD
SELECT:
當隔離級別是REPEATABLE READ時select操作,InnoDB每行數據來保證它符合兩個條件:
** 1 事務的版本號 大於等於 創建行版本號**
** 2 行數據的刪除版本 未定義 或者大於 事務版本號**
【行創建版本號 事務版本號 行刪除版本號】
INSERT:
InnoDB為這個新行 記錄 當前的系統版本號。
DELETE:
InnoDB將當前的系統版本號 設置為 這一行的刪除版本號。
UPDATE:
InnoDB會寫一個這行數據的新拷貝,這個拷貝的版本為 當前的系統版本號。它同時也會將這個版本號 寫到 舊行的刪除版本里。
————————————————
版權聲明:本文為CSDN博主「@Autowire」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:
什麼叫mysql事務?
1. 普通事務
以 begin / start transaction 開始,commit / rollback 結束的事務。或者是帶有保存點 savepoint 的事務。
2. 鏈式事務
一個事務在提交的時候自動將上下文傳給下一個事務,也就是說一個事務的提交和下一個事務的開始是原子性的,下一個事務可以看到上一個事務的處理結果。MySQL 的鏈式事務靠參數 completion_type 控制,並且回滾和提交的語句後面加上 work 關鍵詞。
3. 嵌套事務
有多個 begin / commit / rollback 這樣的事務塊的事務,並且有父子關係。子事務的提交完成後不會真的提交,而是等到父事務提交才真正的提交。
4. 自治事務
內部事務的提交不隨外部事務的影響,一般用作記錄內部事務的異常情況。MySQL 不支持自治事務,但是某些場景可以用 MySQL 的插件式引擎來變相實現。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/206873.html