最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL事務(wù)定義、起源、版本支持與提交方式全面解析

 更新時間:2026年04月28日 09:52:17   作者:小林熬夜學(xué)編程  
數(shù)據(jù)庫處理并發(fā)事務(wù)時,事務(wù)隔離級別是保證數(shù)據(jù)一致性的關(guān)鍵機制,下面這篇文章主要介紹了MySQL事務(wù)定義、起源、版本支持與提交方式的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

先拋出一個問題:CURD不加控制,會有什么問題?

從上面的圖我們可以看到,如果單純的CURD操作可能導(dǎo)致數(shù)據(jù)不一致的問題(線程并發(fā)問題)!

CURD滿足什么屬性,怎么解決上面的問題呢?

  • 1. 買票的過程得是原子(要么買要么不買)的吧
  • 2. 買票互相應(yīng)該不能影響
  • 3. 買完票應(yīng)該要永久有效
  • 4. 買前,和買后都要是確定的狀態(tài)吧 

1、什么是事務(wù)

  • 事務(wù)就是一組DML語句組成,這些語句在邏輯上存在相關(guān)性,這一組DML語句要么全部成功,要么全部失敗,是一個整體。MySQL提供一種機制,保證我們達(dá)到這樣的效果。事務(wù)還規(guī)定不同的客戶端看到的數(shù)據(jù)是不相同的。
  • 事務(wù)就是要做的或所做的事情,主要用于處理操作量大,復(fù)雜度高的數(shù)據(jù)。假設(shè)一種場景:你畢業(yè)了,學(xué)校的教務(wù)系統(tǒng)后臺 MySQL 中,不在需要你的數(shù)據(jù),要刪除你的所有信息(一般不會:) ), 那么要刪除你的基本信息(姓名,電話,籍貫等)的同時,也刪除和你有關(guān)的其他信息,比如:你的各科成績,你在校表現(xiàn),甚至你在論壇發(fā)過的文章等。這樣,就需要多條 MySQL 語句構(gòu)成,那么所有這些操作合起來,就構(gòu)成了一個事務(wù)。

正如我們上面所說,一個 MySQL 數(shù)據(jù)庫,可不止你一個事務(wù)在運行,同一時刻,甚至有大量的請求被包裝成事務(wù),在向 MySQL 服務(wù)器發(fā)起事務(wù)處理請求。而每條事務(wù)至少一條 SQL ,最多很多 SQL ,這樣如果大家都訪問同樣的表數(shù)據(jù),在不加保護的情況,就絕對會出現(xiàn)問題。甚至,因為事務(wù)由多條 SQL 構(gòu)成,那么,也會存在執(zhí)行到一半出錯或者不想再執(zhí)行的情況,那么已經(jīng)執(zhí)行的怎么辦呢?

所有,一個完整的事務(wù),絕對不是簡單的 sql 集合,還需要滿足如下四個屬性

  • 原子性:一個事務(wù)(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。
  • 一致性:在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預(yù)設(shè)規(guī)則,這包含資料的精確度、串聯(lián)性以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預(yù)定的工作。 
  • 隔離性:數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進行讀寫和修改的能力,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。事務(wù)隔離分為不同級別,包括讀未提交( Readuncommitted )、讀提交( read committed )、可重復(fù)讀( repeatable read )和串行化( Serializable )
  • 持久性事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。

上面四個屬性,可以簡稱為 ACID 。

  • 原子性(Atomicity,或稱不可分割性)
  • 一致性(Consistency)
  • 隔離性(Isolation,又稱獨立性)
  • 持久性(Durability)。

2、為什么會出現(xiàn)事務(wù)

事務(wù)被 MySQL 編寫者設(shè)計出來,本質(zhì)是為了當(dāng)應(yīng)用程序訪問數(shù)據(jù)庫的時候,事務(wù)能夠簡化我們的編程模型,不需要我們?nèi)タ紤]各種各樣的潛在錯誤和并發(fā)問題.可以想一下當(dāng)我們使用事務(wù)時,要么提交,要么回滾,我們不會去考慮網(wǎng)絡(luò)異常了,服務(wù)器宕機了,同時更改一個數(shù)據(jù)怎么辦對吧?因此事務(wù)本質(zhì)上是為了應(yīng)用層服務(wù)的.而不是伴隨著數(shù)據(jù)庫系統(tǒng)天生就有的.

  • 備注:我們后面把 MySQL 中的一行信息,稱為一行記錄 

3、事務(wù)的版本支持

在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫引擎的數(shù)據(jù)庫或表才支持事務(wù), MyISAM 不支持。

查看數(shù)據(jù)庫引擎

show engines; -- 表格顯示

show engines \G; -- 行顯示

4、事務(wù)提交方式

事務(wù)的提交方式常見的有兩種:

  • 自動提交
  • 手動提交

查看事務(wù)提交方式

show variables like 'autocommit';

用 SET 來改變 MySQL 的自動提交模式: 

set autocommit = 0; -- 禁止自動提交

set autocommit = 1; -- 開啟自動提交

事務(wù)常見操作方式 

  • 使用netstat查看鏈接情況,可知:mysql本質(zhì)是一個客戶端進程 

為了便于演示,我們將mysql的默認(rèn)隔離級別設(shè)置成讀未提交 

set global transaction isolation level read uncommitted;

創(chuàng)建測試表 

create table if not exists account(
    id int primary key, 
    name varchar(50) not null default ' ', 
    balance decimal(10,2) not null default 0.0 
)engine=InnoDB default charset=utf8;

正常演示 - 證明事務(wù)的開始與回滾

show variables like 'autocommit';  
-- 查看事務(wù)是否自動提交。我們故意設(shè)置成自動提交,看看該選項是否影響begin

start transaction; -- 開始一個事務(wù)begin也可以,推薦begin

savepoint s1; -- 創(chuàng)建一個保存點s1

insert into account values(1,'張三',1263.4); -- 插入一條記錄

savepoint s2; -- 創(chuàng)建一個保存點s2

insert into account values(2,'李四',6521.9); -- 再插入一條記錄

select * from account; -- 兩條記錄都在了
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1263.40 |
|  2 | 李四   | 6521.90 |
+----+--------+---------+
2 rows in set (0.00 sec)

rollback to s2; -- 回滾到保存點save2

select * from account; -- id為2的一條記錄沒有了
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1263.40 |
+----+--------+---------+
1 row in set (0.00 sec)

rollback; -- 直接rollback,回滾在最開始

select * from account; -- 所有剛剛的記錄沒有了
Empty set (0.00 sec)

非正常演示1 - 證明未commit,客戶端崩潰,MySQL自動會回滾(隔離級別設(shè)置為讀未提交)

-- 終端A
select * from account; -- 當(dāng)前表內(nèi)無數(shù)據(jù)

show variables like 'autocommit'; -- 依舊自動提交

begin; --開啟事務(wù)

insert into account values(1,'張三',1566.7); -- 插入記錄

-- 終端B
select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1566.70 |
+----+--------+---------+
1 row in set (0.00 sec)

-- 終端A
mysql> Aborted -- ctrl + \ 異常終止MySQL

-- 終端B
select * from account;
Empty set (0.00 sec)

非正常演示2 - 證明commit了,客戶端崩潰,MySQL數(shù)據(jù)不會在受影響,已經(jīng)持久化 

show variables like 'autocommit'; -- 依舊自動提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
1 row in set (0.00 sec)

select * from account;   -- 當(dāng)前表內(nèi)無數(shù)據(jù)
Empty set (0.00 sec)

begin;                   -- 開啟事務(wù)

insert into account values (1, '張三', 1234.4); -- 插入記錄

commit;                         --提交事務(wù)

Aborted                         -- ctrl + \ 異常終止MySQL

--終端 B
select * from account;          --數(shù)據(jù)存在了,所以commit的作用是將數(shù)據(jù)持久化到MySQL中

非正常演示3 - 對比試驗。證明begin操作會自動更改提交方式,不會受MySQL是否自動提交影響

mysql> select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1234.40 |
+----+--------+---------+
1 row in set (0.00 sec)

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.01 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values(2,'李四',6543.2);
Query OK, 1 row affected (0.00 sec)

mysql> Aborted

非正常演示4 - 證明單條 SQL 與事務(wù)的關(guān)系

實驗一

mysql> select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1234.40 |
+----+--------+---------+
1 row in set (0.00 sec)

mysql> system clear
mysql> select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1234.40 |
+----+--------+---------+
1 row in set (0.00 sec)

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> insert into account values(2,'李四',6532.4);
Query OK, 1 row affected (0.00 sec)

mysql> Aborted

實驗二

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

mysql> select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1234.40 |
+----+--------+---------+
1 row in set (0.00 sec)

mysql> insert into account values(2,'李四',3526.4);
Query OK, 1 row affected (0.01 sec)

mysql> select * from account;
+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 張三   | 1234.40 |
|  2 | 李四   | 3526.40 |
+----+--------+---------+
2 rows in set (0.01 sec)

mysql> Aborted

結(jié)論:

  • 只要輸入begin或者start transaction,事務(wù)便必須要通過commit提交,才會持久化,與是否設(shè)置set autocommit無關(guān)。
  • 事務(wù)可以手動回滾,同時,當(dāng)操作異常,MySQL會自動回滾
  • 對于 InnoDB 每一條 SQL 語言都默認(rèn)封裝成事務(wù),自動提交。(select有特殊情況,因為MySQL 有 MVCC )
  • 從上面的例子,我們能看到事務(wù)本身的原子性(回滾),持久性(commit)
  • 那么隔離性?一致性?

事務(wù)操作注意事項

  • 如果沒有設(shè)置保存點,也可以回滾,只能回滾到事務(wù)的開始。直接使用 rollback(前提是事務(wù)還沒有提交)
  • 如果一個事務(wù)被提交了(commit),則不可以回退(rollback)
  • 可以選擇回退到哪個保存點
  • InnoDB 支持事務(wù), MyISAM 不支持事務(wù)
  • 開始事務(wù)可以使 start transaction 或者 begin 

總結(jié) 

到此這篇關(guān)于MySQL事務(wù)定義、起源、版本支持與提交方式的文章就介紹到這了,更多相關(guān)MySQL事務(wù)詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

靖州| 株洲县| 洛阳市| 盐津县| 防城港市| 凤台县| 磴口县| 凤庆县| 莱州市| 高台县| 宁城县| 河源市| 裕民县| 韶山市| 富宁县| 平遥县| 泗洪县| 睢宁县| 株洲县| 连州市| 四会市| 新兴县| 宜都市| 建宁县| 密山市| 安平县| 玛沁县| 信阳市| 肥城市| 教育| 尼木县| 资中县| 余江县| 西林县| 根河市| 钦州市| 克东县| 彰武县| 黑水县| 中西区| 勃利县|