自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL事務(wù)及并發(fā)下所引發(fā)的問題詳解

數(shù)據(jù)庫 MySQL
保證所有的操作都作為 一個(gè)工作單元來執(zhí)行,即使出現(xiàn)了異常,都不能改變這種執(zhí)行方式。當(dāng)在一個(gè)事務(wù)中執(zhí)行多個(gè)操作時(shí),要么所有的事務(wù)都被提交( commit ),這些修改永久地保存下來;要么放棄所有的修改 ,整個(gè)事務(wù)回滾( rollback )到最初狀態(tài)。

環(huán)境:MySQL8.0.30

1 事務(wù)基本概念

1.1 基本概念

什么是事務(wù):是可以提交或回滾的原子工作單元,它是由一個(gè)或多個(gè)操作形成的一組操作單元。

事務(wù)處理的原則:保證所有的操作都作為 一個(gè)工作單元來執(zhí)行,即使出現(xiàn)了異常,都不能改變這種執(zhí)行方式。當(dāng)在一個(gè)事務(wù)中執(zhí)行多個(gè)操作時(shí),要么所有的事務(wù)都被提交( commit ),這些修改永久地保存下來;要么放棄所有的修改 ,整個(gè)事務(wù)回滾( rollback )到最初狀態(tài)。

1.2 事務(wù)的四個(gè)特性ACID

1.2.1 原子性

Atomicity

是指事務(wù)是一個(gè)不可分割的工作單位( 最小的工作單位 ),要么全部提交,要么全部回滾。

1.2.2 一致性

Consistency

一致性是指事務(wù)執(zhí)行前后,數(shù)據(jù)從一個(gè) 合法性狀態(tài) 變換到另外一個(gè) 合法性狀態(tài);而這種狀態(tài)應(yīng)該是與具體的業(yè)務(wù)相關(guān)。

該特性是由其它3個(gè)特性 + 開發(fā)者共同來保證的。

如:張三給李四轉(zhuǎn)賬100,張三的賬戶必須扣減100元,李四的賬戶必須加100元。

1.2.3 隔離性

Isolation

事務(wù)的隔離性是指一個(gè)事務(wù)的執(zhí)行 不能被其他事務(wù)干擾 ,即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。

如不考慮事務(wù)的隔離性,將會(huì)出現(xiàn)如下情況:

圖片

1.2.4 持久性

Durability

指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,即使系統(tǒng)服務(wù)器奔潰或者服務(wù)器宕機(jī),只要數(shù)據(jù)庫能夠重新啟動(dòng),那么一定會(huì)將其恢復(fù)為事務(wù)提交成功結(jié)束后的狀態(tài)。

1.3 MySQL事務(wù)支持

圖片

只有InnoDB引擎是支持事務(wù)的。

2 如何使用事務(wù)

兩種方式:顯式事務(wù) 和 隱式事務(wù)

2.1 顯示事務(wù)

顯示事務(wù)可以通過2中方式:start transaction 或 beign。

mysql> START TRANSACTION;
 Query OK, 0 rows affected (0.00 sec)
 或者
 mysql> BEGIN;
 Query OK, 0 rows affected (0.00 sec)
 
 #這里是一組DML語句
 
 #提交事務(wù)
 mysql> COMMIT;
 Query OK, 0 rows affected (0.00 sec)
 
 #回滾事務(wù)
 mysql> ROLLBACK;
 Query OK, 0 rows affected (0.00 sec)

兩者的區(qū)別在于,start transaction [修飾符]

  1. READ ONLY:標(biāo)識(shí)當(dāng)前事務(wù)是一個(gè)只讀事務(wù) ,也就是屬于該事務(wù)的數(shù)據(jù)庫操作只能讀取數(shù)據(jù),而不能修改數(shù)據(jù)。
  2. READ WRITE:標(biāo)識(shí)當(dāng)前事務(wù)是一個(gè)讀寫事務(wù) ,也就是屬于該事務(wù)的數(shù)據(jù)庫操作既可以讀取數(shù)據(jù),也可以修改數(shù)據(jù)。
  3. WITH CONSISTENT SNAPSHOT :?jiǎn)?dòng)一致性快照讀。(唯一允許一致性讀的隔離級(jí)別是REPEATABLE READ,對(duì)于所有其他隔離級(jí)別,將忽略WITH CONSISTENT SNAPSHOT子句。當(dāng)忽略WITH CONSISTENT SNAPSHOT子句時(shí),將生成一個(gè)警告。)

什么是一致性快照讀?如下示例:

創(chuàng)建如下表

mysql> create table test (id int primary key, name varchar(32));
 Query OK, 0 rows affected (0.05 sec)
 
 mysql> select * from test;
 Empty set (0.00 sec)

試驗(yàn)1:

圖片

試驗(yàn)2:

圖片

結(jié)論:

START TRANSACTION是在第一條select執(zhí)行完后,才得到事務(wù)的一致性快照,而START TRANSACTION WITH CONSISTENT SNAPSHOT則是立馬取得事務(wù)的一致性快照。

2.2 隱式事務(wù)

通過設(shè)置autocommit系統(tǒng)變量來控制事務(wù),默認(rèn)該值為:ON。

mysql> SHOW VARIABLES LIKE '%autocommit%';
 +---------------+-------+
 | Variable_name | Value |
 +---------------+-------+
 | autocommit    | ON    |
 +---------------+-------+
 1 row in set (0.01 sec)

默認(rèn)事務(wù)自動(dòng)提交。、

通過如下方式進(jìn)行關(guān)閉

mysql> SET AUTOCOMMIT=OFF;
 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> SET AUTOCOMMIT=0;

2.3 使用事務(wù)

創(chuàng)建數(shù)據(jù)庫及表

mysql> create database pack;
 Query OK, 1 row affected (0.01 sec)
 
 mysql> use pack;
 Database changed
 mysql> create table test (id int primary key, name varchar(32));
 Query OK, 0 rows affected (0.09 sec)

示例1:

mysql> begin;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> insert into test values (1, 'zs');
 Query OK, 1 row affected (0.01 sec)
 
 mysql> insert into test values (2, 'ls');
 Query OK, 1 row affected (0.00 sec)
 
 mysql> commit;
 Query OK, 0 rows affected (0.01 sec)
 
 mysql> select * from test;
 +----+------+
 | id | name |
 +----+------+
 |  1 | zs   |
 |  2 | ls   |
 +----+------+
 2 rows in set (0.00 sec)

示例2:

mysql> begin;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> insert into test values (3, 'ww');
 Query OK, 1 row affected (0.00 sec)
 
 mysql> insert into test values (4, 'zl');
 Query OK, 1 row affected (0.00 sec)
 
 mysql> rollback;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> select * from test;
 +----+------+
 | id | name |
 +----+------+
 |  1 | zs   |
 |  2 | ls   |
 +----+------+
 2 rows in set (0.00 sec)

2.4 事務(wù)保存點(diǎn)

MySQL支持SAVEPOINT、ROLLBACK TO SAVEPOINT、RELEASE SAVEPOINT。

通過設(shè)置保存點(diǎn),事務(wù)回滾是回滾到指定的保存點(diǎn),而不是回滾整個(gè)事務(wù)。

示例:

mysql> select * from test;
 +----+------+
 | id | name |
 +----+------+
 |  1 | zs   |
 |  2 | ls   |
 +----+------+
 2 rows in set (0.00 sec)
 
 mysql> begin;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> insert into test values (3, 'zl');
 Query OK, 1 row affected (0.00 sec)
 
 mysql> savepoint p1;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> insert into test values (4, 'ww');
 Query OK, 1 row affected (0.00 sec)
 
 mysql> rollback to p1;
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> commit;
 Query OK, 0 rows affected (0.02 sec)
 
 mysql> select * from test;
 +----+------+
 | id | name |
 +----+------+
 |  1 | zs   |
 |  2 | ls   |
 |  3 | zl   |
 +----+------+
 3 rows in set (0.00 sec)

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

3.1 環(huán)境準(zhǔn)備

創(chuàng)建表:

mysql> create table account (
     -> id int primary key,
     -> name varchar(32),
     -> balance int
     -> );
 Query OK, 0 rows affected (0.06 sec)

插入數(shù)據(jù)

mysql> insert into account values (1, 'zs', 1000);
 
 mysql> select * from account;
 +----+------+---------+
 | id | name | balance |
 +----+------+---------+
 |  1 | zs       |    1000  |
 +----+------+---------+
 1 row in set (0.00 sec)

3.2 并發(fā)問題

當(dāng)多個(gè)事務(wù)并發(fā)執(zhí)行修改相同數(shù)據(jù)時(shí)會(huì)出現(xiàn)如下問題:

3.2.1 臟寫

一個(gè)事務(wù)修改了另外一個(gè)事務(wù)修改了但未提交的數(shù)據(jù)。

臟寫非常的嚴(yán)重,以致所有的隔離級(jí)別都解決了臟寫問題。

3.2.2 臟讀

事務(wù)A讀取了事務(wù)B修改了但是未提交的數(shù)據(jù),如果此時(shí)事務(wù)B回滾了,那么事務(wù)A讀取到的數(shù)據(jù)肯定是無效的。

3.2.3 不可重復(fù)讀

事務(wù)A讀取id為1的name為張三,緊接著事務(wù)B修改了id為1的name為李四,此時(shí)事務(wù)A再次讀取id為1的數(shù)據(jù)發(fā)現(xiàn)此時(shí)name為李四,事務(wù)A兩次讀取不一樣,這就是發(fā)生了不可重復(fù)讀。

3.2.4 幻讀

事務(wù)A讀取age為20的人人員信息返回了10條,緊接著事務(wù)B插入了5條age為20的數(shù)據(jù),此時(shí)事務(wù)A再次讀取age為20的人員信息返回15條,這就是發(fā)生了幻讀。

3.3 隔離級(jí)別

MySQL支持4中隔離級(jí)別,Oracle支持兩種(READ COMMITTED(默認(rèn)), SERIALIZABLE)

3.3.1 讀未提交

READ UNCOMMITTED:讀未提交,在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果;不能避免臟讀、不可重復(fù)讀、幻讀。

3.3.2 讀已提交

READ COMMITTED:一個(gè)事務(wù)讀取到了,其它已提交的事務(wù)所修改的數(shù)據(jù);可以避免臟讀,但不可重復(fù)讀、幻讀問題仍然存在。

3.3.3 可重復(fù)讀

REPEATABLE READ:事務(wù)A讀取一條數(shù)據(jù)后,事務(wù)B修改了該數(shù)據(jù)并且提交后,事務(wù)A再次讀取該條數(shù)據(jù),讀取到的內(nèi)容沒有發(fā)生變化;可以避免臟讀、不可重復(fù)讀,但幻讀問題仍

然存在。MySQL默認(rèn)隔離級(jí)別

3.3.4 串行化

SERIALIZABLE:一個(gè)一個(gè)的按順序執(zhí)行;能避免臟讀、不可重復(fù)讀和幻讀。

總結(jié),在不同隔離級(jí)別下,并發(fā)事務(wù)所引發(fā)的問題如下

不同隔離級(jí)別下所帶來的性能問題

3.4 隔離級(jí)別演示

MySQL中設(shè)置隔離級(jí)別方法如下:

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔離級(jí)別;
 #其中,隔離級(jí)別格式:
 1. READ UNCOMMITTED
 2. READ COMMITTED
 3. REPEATABLE READ
 4. SERIALIZABLE

或者

SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔離級(jí)別'
 #其中,隔離級(jí)別格式:
 1. READ-UNCOMMITTED
 2. READ-COMMITTED
 3. REPEATABLE-READ
 4. SERIALIZABLE

示例:

mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
 Query OK, 0 rows affected (0.00 sec)
 #或者
 mysql> SET SESSION TRANSACTION_ISOLATION ='REPEATABLE-READ';
 Query OK, 0 rows affected (0.00 sec)
 #查看當(dāng)前會(huì)話級(jí)別的隔離級(jí)別
 mysql> SELECT @@TRANSACTION_ISOLATION;
 +-------------------------+
 | @@TRANSACTION_ISOLATION |
 +-------------------------+
 | REPEATABLE-READ         |
 +-------------------------+
 1 row in set (0.00 sec)

3.4.1 讀未提交

臟讀問題

mysql> set session transaction_isolatinotallow='READ-UNCOMMITTED';
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> select @@transaction_isolation;
 +-------------------------+
 | @@transaction_isolation |
 +-------------------------+
 | READ-UNCOMMITTED        |
 +-------------------------+
 1 row in set (0.00 sec)

示例:

3.4.2 讀已提交

不可重復(fù)讀

mysql> set session transaction_isolatinotallow='read-committed';
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> select @@transaction_isolation;
 +-------------------------+
 | @@transaction_isolation |
 +-------------------------+
 | READ-COMMITTED          |
 +-------------------------+
 1 row in set (0.00 sec)

示例:

圖片


3.4.3 可重復(fù)讀

mysql> set session transaction_isolatinotallow='REPEATABLE-READ';
 Query OK, 0 rows affected (0.00 sec)
 
 mysql> select @@transaction_isolation;
 +-------------------------+
 | @@transaction_isolation |
 +-------------------------+
 | REPEATABLE-READ         |
 +-------------------------+
 1 row in set (0.00 sec)

示例:

圖片


嚴(yán)格意義上看,可重復(fù)讀隔離級(jí)別并沒有解決幻讀問題

示例:

圖片


3.4.4 串行化

排隊(duì)執(zhí)行,略

完畢?。?!

責(zé)任編輯:武曉燕 來源: 實(shí)戰(zhàn)案例錦集
相關(guān)推薦

2010-09-02 14:59:23

非授權(quán)DHCP

2023-07-06 07:55:15

Redis內(nèi)存數(shù)據(jù)庫

2013-01-30 10:12:24

NginxNginx優(yōu)化高并發(fā)

2014-08-08 13:30:44

Nginx

2011-10-17 08:29:33

Ubuntu 11.1思考

2023-02-10 07:00:22

2024-09-29 00:00:00

高并發(fā)交易所宕機(jī)

2018-05-04 15:15:37

數(shù)據(jù)庫MySQL并發(fā)場(chǎng)景

2019-07-05 17:40:24

MySQL并發(fā)數(shù)據(jù)庫

2023-08-25 08:06:20

CPUMySQL線程

2021-01-15 05:12:14

Java并發(fā)樂觀鎖

2025-02-20 00:01:00

2012-10-11 14:42:19

FastDFS

2022-09-13 13:49:05

數(shù)據(jù)庫隔離

2012-02-02 15:57:09

HibernateJava

2019-10-30 16:54:08

golangredis數(shù)據(jù)庫

2023-10-13 08:11:22

2022-06-12 06:45:26

高并發(fā)防重

2024-10-18 10:04:01

2016-12-20 12:42:28

MySQL腳本問題
點(diǎn)贊
收藏

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