1. 程式人生 > >MySQL資料庫事務略知一二

MySQL資料庫事務略知一二

事務的概念

事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。
例如:A向B轉賬100元,對應於如下兩條sql語句:

update from account set money=money+100 where name='b';
update from account set money=money-100 where name='a';

資料庫預設事務是自動提交的,也就是發一條sql它就執行一條,如果想多條sql放在一個事務中執行,則需要使用如下語句:

start transaction
…
…
commit

資料庫開啟事務命令:

  • start transaction
    :開啟事務
  • rollback:回滾事務
  • commit:提交事務

MySQL資料庫中操作事務命令

編寫測試SQL指令碼,如下:

/* 建立資料庫 */
create database day16;

use day16;

/* 建立賬戶表 */
create table account 
(
    id int primary key auto_increment,
    name varchar(40),
    money float
) character set utf8 collate utf8_general_ci;

/* 插入測試資料 */
insert into account(name,money) values
('aaa',1000);
insert into account(name,money) values('bbb',1000); insert into account(name,money) values('ccc',1000);

下面我們在MySQL資料庫中模擬aaa向bbb轉帳這個業務場景。

  • 開啟事務(start transaction)
    使用”start transaction”開啟MySQL資料庫的事務,如下所示:
    這裡寫圖片描述
    我們首先在資料庫中模擬轉賬失敗的場景,首先執行update語句讓aaa使用者的money減少100塊錢,如下圖所示:
    這裡寫圖片描述
    現在假設程式丟擲異常,也即該連結斷了,程式碼塊沒有完成,此時資料庫會自動回滾掉此sql語句造成的影響,也就是說這條sql語句沒有執行。我們現在就來模擬這種情況,我們關閉當前操作的dos命令列視窗,這樣就導致了剛才執行的update語句的資料庫的事務沒有被提交,那麼我們對aaa使用者的修改就不算是真正的修改了,下次在查詢aaa使用者的money時,依然還是之前的1000,如下圖所示:
    這裡寫圖片描述

  • 提交事務(commit)
    下面我們在資料庫模擬aaa向bbb轉賬成功的場景。
    這裡寫圖片描述
    我們手動提交(commit)資料庫事務之後,aaa向bbb轉賬100塊錢的這個業務操作算是真正成功了,aaa賬戶中少了100,bbb賬戶中多了100。

  • 回滾事務(rollback)
    這裡寫圖片描述
    通過手動回滾事務,讓所有的操作都失效,這樣資料就會回到最初的初始狀態!

JDBC中使用事務

當Jdbc程式向資料庫獲得一個Connection物件時,預設情況下這個Connection物件會自動向資料庫提交在它上面傳送的SQL語句。若想關閉這種預設提交方式,讓多條SQL在一個事務中執行,可使用下列的JDBC控制事務語句:

  • Connection.setAutoCommit(false); //開啟事務(start transaction)
  • Connection.rollback(); //回滾事務(rollback)
  • Connection.commit(); //提交事務(commit)

JDBC使用事務範例

在JDBC程式碼中演示銀行轉帳案例,使如下轉帳操作在同一事務中執行:

update from account set money=money-100 where name=‘aaa’;
update from account set money=money+100 where name=‘bbb’;
  • 模擬aaa向bbb轉賬成功時的業務場景

    public class Demo1 {
    
        /*
         * a--->b轉100元
         */
        public static void main(String[] args) throws SQLException {
    
            Connection conn = null;
            PreparedStatement st = null;
            ResultSet rs = null;
    
            try {
                conn = JdbcUtils.getConnection();
                conn.setAutoCommit(false); // 相當於start transaction,開啟事務
    
                String sql1 = "update account set money=money-100 where name='aaa'";
                String sql2 = "update account set money=money+100 where name='bbb'";
    
                st = conn.prepareStatement(sql1);
                st.executeUpdate();
    
                st = conn.prepareStatement(sql2);
                st.executeUpdate();
    
                conn.commit();
            } finally {
                JdbcUtils.release(conn, st, rs);
            }
        }
    
    }
  • 模擬aaa向bbb轉賬過程中出現異常導致有一部分SQL執行失敗後讓資料庫自動回滾事務

    public class Demo1 {
    
        /*
         * a--->b轉100元
         */
        public static void main(String[] args) throws SQLException {
    
            Connection conn = null;
            PreparedStatement st = null;
            ResultSet rs = null;
    
            try {
                conn = JdbcUtils.getConnection();
                conn.setAutoCommit(false); // 相當於start transaction,開啟事務
    
                String sql1 = "update account set money=money-100 where name='aaa'";
                String sql2 = "update account set money=money+100 where name='bbb'";
    
                st = conn.prepareStatement(sql1);
                st.executeUpdate();
    
                int x = 1/0; // 程式執行到這個地方拋異常,後面的程式碼就不執行,資料庫沒有收到commit命令
    
                st = conn.prepareStatement(sql2);
                st.executeUpdate();
    
                conn.commit();
            } finally {
                JdbcUtils.release(conn, st, rs);
            }
        }
    
    }
  • 模擬aaa向bbb轉賬過程中出現異常導致有一部分SQL執行失敗時手動通知資料庫回滾事務

    public class Demo1 {
    
        /*
         * a--->b轉100元
         */
        public static void main(String[] args) throws SQLException {
    
            Connection conn = null;
            PreparedStatement st = null;
            ResultSet rs = null;
    
            try {
                conn = JdbcUtils.getConnection();
                conn.setAutoCommit(false); // 相當於start transaction,開啟事務
    
                String sql1 = "update account set money=money-100 where name='aaa'";
                String sql2 = "update account set money=money+100 where name='bbb'";
    
                st = conn.prepareStatement(sql1);
                st.executeUpdate();
    
                int x = 1/0; // 程式執行到這個地方拋異常,後面的程式碼就不執行,資料庫沒有收到commit命令
    
                st = conn.prepareStatement(sql2);
                st.executeUpdate();
    
                conn.commit();
            } catch (Exception e) {
                e.printStackTrace();
                conn.rollback(); // 捕獲到異常之後手動通知資料庫執行回滾事務的操作
            } finally {
                JdbcUtils.release(conn, st, rs);
            }
        }
    
    }

設定事務回滾點

在開發中,有時候可能需要手動設定事務的回滾點,在JDBC中使用如下的語句設定事務回滾點:

Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit(); // 回滾後必須通知資料庫提交事務

設定事務回滾點範例:

public class Demo2 {

    // 事務回滾點概念
    public static void main(String[] args) throws SQLException {

        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        Savepoint sp = null;

        try {
            conn = JdbcUtils.getConnection(); // MySQL預設的隔離級別——REPEATABLE-READ,並且是嚴格遵循資料庫規範設計的,即支援4種隔離級別
                                              // Oracle預設的隔離級別——Read committed,並且不支援這4種隔離級別,只支援這4種隔離級別中的2種,Read committed和Serializable
            // conn.setTransactionIsolation(); // 相當於設定CMD視窗的隔離級別
            conn.setAutoCommit(false); // 相當於start transaction,開啟事務

            // 不符合實際需求
            String sql1 = "update account set money=money-100 where name='aaa'";
            String sql2 = "update account set money=money+100 where name='bbb'";
            String sql3 = "update account set money=money+100 where name='ccc'";

            st = conn.prepareStatement(sql1);
            st.executeUpdate();
            /*
             * 只希望回滾掉這一條sql語句,上面那條sql語句讓其執行成功
             * 這時可設定事務回滾點
             */
            sp = conn.setSavepoint();

            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            int x = 1/0; // 程式執行到這個地方拋異常,後面的程式碼就不執行,資料庫沒有收到commit命令

            st = conn.prepareStatement(sql3);
            st.executeUpdate();

            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
            conn.rollback(sp); // 回滾到sp點,sp點上面的sql語句發給資料庫執行,由於資料庫沒收到commit命令,資料庫又會自動將這條sql語句的影響回滾掉,所以回滾完,一定要記得commit命令。
            conn.commit(); // 手動回滾後,一定要記得提交事務
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }
}

事務的四大特性(ACID)

  • 原子性(Atomicity)
    原子性是指事務是一個不可分割的工作單位,事務中的操作要麼全部成功,要麼全部失敗。比如在同一個事務中的SQL語句,要麼全部執行成功,要麼全部執行失敗。
  • 一致性(Consistency)
    官網上事務一致性的概念是:事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。還要一種說法是事務前後資料的完整性必須保持一致。以轉賬為例子,A向B轉賬,假設轉賬之前這兩個使用者的錢加起來總共是2000,那麼A向B轉賬之後,不管這兩個賬戶怎麼轉,A使用者的錢和B使用者的錢加起來的總額還是2000,這個就是事務的一致性。
  • 隔離性(Isolation)
    事務的隔離性是多個使用者併發訪問資料庫時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作資料所幹擾,多個併發事務之間要相互隔離。
  • 永續性(Durability)
    永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來即使資料庫發生故障也不應該對其有任何影響。

事務的隔離級別

事務的四大特性中最麻煩的是隔離性,下面重點介紹一下事務的隔離級別。
多個執行緒開啟各自事務操作資料庫中資料時,資料庫系統要負責隔離操作,以保證各個執行緒在獲取資料時的準確性。

事務不考慮隔離性可能會引發的問題

如果事務不考慮隔離性,可能會引發如下問題:

  • 髒讀
    指一個事務讀取了另外一個事務未提交的資料
    這是非常危險的,假設a向b轉帳100元,對應sql語句如下所示:

    1.update account set money=money+100 while name=‘b’;    
    2.update account set money=money-100 while name=‘a’;
    

    當第1條sql執行完,第2條還沒執行(a未提交時),如果此時b查詢自己的帳戶,就會發現自己多了100元錢。如果a等b走後再回滾,b就會損失100元。

  • 不可重複讀
    在一個事務內讀取表中的某一行資料,多次讀取結果不同。(一個事務讀取到了另外一個事務提交的資料
    例如銀行想查詢a帳戶餘額,第一次查詢a帳戶為200元,此時a向帳戶記憶體了100元並提交了,銀行接著又進行了一次查詢,此時a帳戶為300元了。銀行兩次查詢不一致,可能就會很困惑,不知道哪次查詢是準的。可將例子簡化為:讀表中某一行資料,例如a賬戶第一次讀為1000,第二次讀為1100
    不可重複讀髒讀的區別是,髒讀是讀取前一事務未提交的髒資料,不可重複讀是重新讀取了前一事務已提交的資料
    很多人認為這種情況就對了,無須困惑,當然是以後面的結果為準了。我們可以考慮這樣一種情況,比如銀行程式需要將查詢結果分別輸出到電腦螢幕和寫到檔案中,結果在一個事務中針對輸出的目的地,進行的兩次查詢不一致,導致檔案和螢幕中的結果不一致,銀行工作人員就不知道以哪個為準了。
  • 虛讀(幻讀)
    虛讀(幻讀)是指在一個事務內讀取到了別的事務插入的資料,導致前後讀取不一致。
    如丙存款100元未提交,這時銀行做報表統計account表中所有使用者的總額為500元,然後丙提交了,這時銀行再統計發現帳戶為600元了,造成虛讀同樣會使銀行不知所措,到底以哪個為準。可將例子簡化為:讀整個表,即表的行數,例如第一次讀某個表有3條記錄,第二次讀該表又有4條記錄

資料庫共定義了四種隔離級別,應用《高效能mysql》一書中有說明:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

  • Serializable(序列化):可避免髒讀、不可重複讀、虛讀情況的發生。
  • Repeatable read(可重複讀):可避免髒讀、不可重複讀情況的發生。
  • Read committed(讀已提交):可避免髒讀情況發生。
  • Read uncommitted(讀未提交):最低級別,以上情況均無法保證。

總結:在MySQL中,實現了這四種隔離級別,分別有可能產生問題如下所示:
這裡寫圖片描述

下面說說修改事務隔離級別的方法:

  1. 全域性修改,修改my.ini(或mysql.ini)配置檔案,在最後加上

    
    #可選引數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
    
    [mysqld]
    transaction-isolation = REPEATABLE-READ

    注意:MySQL預設的隔離級別為REPEATABLE-READ,並且是嚴格遵循資料庫規範設計的,即支援4種隔離級別;Oracle預設的隔離級別為Read committed,並且不支援這4種隔離級別,只支援這4種隔離級別中的2種,Read committed和Serializable

  2. 對當前session修改,在登入mysql客戶端後,執行命令:

    set session transaction isolation level read uncommitted; // 設定當前事務隔離級別

    注意:session是不能掉的,不然你設定不會成功,MySQL的隔離級別還是預設的隔離級別——REPEATABLE-READ,如下所示:
    這裡寫圖片描述

查詢當前事務隔離級:

select @@tx_isolation; // 查詢當前事務隔離級別

下面,將利用MySQL的客戶端程式,分別測試幾種隔離級別。測試資料庫為day16,表為account;表如下:
這裡寫圖片描述
兩個命令列客戶端分別為a(黑色背景視窗),b(藍色背景視窗);不斷改變b的隔離級別,在a端修改資料。

  • 將b的隔離級別設定為read uncommitted(未提交讀)
    在a未更新資料之前,b客戶端
    這裡寫圖片描述
    a更新資料,a向b轉帳100元
    這裡寫圖片描述
    此時b查詢自己的帳戶,就會發現自己多了100元錢,出現了髒讀(這個事務讀取到了別的事務未提交的資料)
    這裡寫圖片描述
    如果a等b走後再回滾 
    這裡寫圖片描述
    此時b查詢自己的帳戶,發現又少掉了100元錢,兩次讀取的資料不一樣,出現不可重複讀現象
    這裡寫圖片描述
    a提交完事務,再開啟一個事務,向表account中新增一條記錄
    這裡寫圖片描述
    此時b再次查詢account表,發現表account中多了一條記錄,出現幻讀現象
    這裡寫圖片描述
  • 將客戶端b的事務隔離級別設定為read committed(已提交讀)
    在a未更新資料之前,b客戶端
    這裡寫圖片描述
    a更新資料,a向b轉帳100元
    這裡寫圖片描述
    b查詢自己的帳戶,金額沒有發生任何變化,說明已提交讀隔離級別解決了髒讀的問題
    這裡寫圖片描述
    a此刻提交事務
    這裡寫圖片描述
    b再次查詢自己的帳戶,發現自己又多了100元錢,這時就發生不可重複讀(指這個事務讀取到了別的事務提交的資料)
    這裡寫圖片描述
    a再開啟一個事務,向表account中新增一條記錄
    這裡寫圖片描述
    然後b再次查詢account表,發現表account中多了一條記錄,出現幻讀現象
    這裡寫圖片描述
  • 將b的隔離級別設定為repeatable read(可重複讀)
    在a未更新資料之前,b客戶端
    這裡寫圖片描述
    a更新資料,a向b轉帳100元
    這裡寫圖片描述
    b查詢自己的帳戶,金額沒有發生任何變化,這說明repeatable read這種級別可避免髒讀
    這裡寫圖片描述
    a此刻提交事務
    這裡寫圖片描述
    b再次查詢自己的帳戶,金額沒有發生任何變化,這說明repeatable read這種級別還可以避免不可重複讀
    這裡寫圖片描述
    a再開啟一個事務,向表account中新增一條記錄
    這裡寫圖片描述
    然後b再次查詢account表,發現表中可能會多出一條ddd的記錄(也有可能不會多出一條ddd的記錄,我測試時就是這種情況),這就發生了虛讀,也就是在這個事務內讀取了別的事務插入的資料(幻影資料)
    這裡寫圖片描述
  • 將b的隔離級別設定為可序列化 (Serializable)
    為可序列化 (Serializable)均可避免髒讀、不可重複讀、幻讀。避免髒讀和不可重複讀的情況我就不測試了,測試步驟同上,下面我重點講解可序列化 (Serializable)避免幻讀的情況。
    事務b端
    這裡寫圖片描述
    事務a端
    這裡寫圖片描述
    因為此時事務b的隔離級別設定為serializable,開始事務後,並沒有提交,所以事務a只能等待。
    事務b提交事務,事務b端
    這裡寫圖片描述
    事務a端
    這裡寫圖片描述
    serializable完全鎖定欄位,若一個事務來查詢同一份資料就必須等待,直到前一個事務完成並解除鎖定為止,是完整的隔離級別,會鎖定對應的資料表格,因而會有效率的問題。
    結論:Serializable隔離級別,雖然可避免所有問題,但效能、效率是最低的,原因是它採取的是鎖表的方式,即單執行緒的方式,即有一個事務來操作這個表了,另外一個事務只能等在外面進不來

下面,將利用java程式來測試Serializable隔離級別。

public class Demo3 {

    public static void main(String[] args) throws SQLException, InterruptedException {

        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        Savepoint sp = null;

        try {
            conn = JdbcUtils.getConnection();
            conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); // 相當於設定CMD視窗的隔離級別
            conn.setAutoCommit(false);

            String sql = "select * from account";
            conn.prepareStatement(sql).executeQuery();

            // 故意讓程式睡眠20秒,睡眠20秒之後事務才結束,程式執行完
            Thread.sleep(1000*20);

            conn.commit();
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }

}

程式執行,同時在客戶端開啟一個事務,插入一條記錄,需要等待一段時間才能插入進去。

相關推薦

MySQL資料庫事務略知一二

事務的概念 事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。 例如:A向B轉賬100元,對應於如下兩條sql語句: update from account set money=money+100 where name='b

mysql資料庫 事務和索引

1.MySQL資料庫特性:  原子性(atomidity) 一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交成功,要麼全部失敗回滾,對於一個事務來說,不可能只執行其中的一部分操作,這就是事務的原子性 一致性(consistency) 資料庫總是從一個一致性的狀態

遇到mysql資料庫事務隔離級別相關的小坑

幾乎所有軟體工程師都知道,mysql有4種事務隔離級別,但是實際開發過程中可能有時候忽略這個小細節,有時候可能是本來就沒有考慮過,有時候也可能是其他的原因,比如我這次踩到的小坑。 事情還原: 1、需求一:是新建一個商戶,但是客戶要求在建立商戶的時候要預設給他們開

MySQL資料庫事務處理

事務處理用於有效記錄某機構感興趣的業務活動(稱為事務)的資料處理(例如銷售、供貨的定購或貨幣傳輸)。通常,聯機事務處理 (OLTP) 系統執行大量的相對較小的事務。——百度百科 事務處理是將多個操作或者命令一起執行,所有命令全部成功執行才意味著該事務的成功,任何一個命令失敗

MYSQL資料庫事務4種隔離級別及7種傳播行為

事務的特性: 原子性:事務的不可分割,組成事務的各個邏輯單元不可分割。 一致性:事務執行的前後,資料完整性保持一致。 隔離性:事務執行不應該受到其他事務的干擾。 永續性:事務一旦結束,資料就持久化到資料庫中。 檢視/設定隔離級別    檢視:SELECT @@tx

mysql資料庫——事務

為什麼會有事務:為了保證流程的完整執行。 事務是一組不可被分割的SQL語句的集合,是一組連續的資料庫操作, 作為一個單一的工作單元來執行。這一組操作要麼全部成功執行,要麼全部回滾 最經典的就是銀行轉賬,一個轉出,一個收到。 mysql 事務主要用於處理操作量大,複雜度高的資料, 事物處

MySQL資料庫事務例項(模擬銀行轉賬)

在資料庫系列文章中[MySQL資料庫事務基本操作](http://blog.csdn.net/fengpojian/article/details/73571983) 介紹了MySQL資料庫基本的事務操作。這篇文章將介紹一個例項來更好的理解學習MySQL資料庫事

c語言mysql資料庫事務開始、提交、回滾範例

1、 事務提交模式修改:修改資料庫提交模式為0[手動提交] memset ( sql, 0x00, sizeof( sql ) ); memcpy ( sql, "set autocommit=0;"

MySQL資料庫事務隔離級別(Transaction Isolation Level)

今天在學習JDBC的時候看到了關於MySql的事務的隔離級別的問題,感覺內容挺高階的,所以記錄一篇文章,以備後面使用。 資料庫隔離級別有四種,應用《高效能mysql》一書中的說明: 然後說說修改事務隔離級別的方法: 1.全域性修改,修改mysql.in

[MySQL] 生產環境MySQL資料庫事務一直在RUNNING

前言:運營人員反映,有一單子提交卡住了,頁面一直沒有返回。1,剛開始懷疑是應用伺服器或者db壓力過高hang住了,馬上去check應用伺服器以及db的負載,看起來都OK,蠻低的,應該不是DB效能問題。2,最後去看下是否是表鎖住了,檢視到有2個事務一直RUNNING,沒有結束。

MySQL資料庫事務基本操作

這篇日誌是自己學習了MySQL資料庫的事務之後,總結的一點心得體會。都是一些非常基礎的知識點。如能幫助諸位初學者,那真是我的榮幸。 資料庫的事務,很多的部落格也都有了詳細的介紹。最基本的事務特性啊(ACID)這裡就不再贅述。 首先,如果想要開啟MySQL資料庫的

MySql資料庫事務的4大特性

這個問題經常會在一些面試題中被問到。總得來說,資料庫事務的4大特性可以簡稱為ACID。 1、原子性(Atomicity) 事務中包含的程式作為資料庫的邏輯工作單位,它對資料庫中的資料進行操作時,要麼全部執行,要麼都不執行。 舉個例子,你給小A轉賬500塊時。這個時候銀行的資

MySQL資料庫事務的四大特性以及事務的隔離級別

目錄 一、事務的四大特性(ACID) 如果一個數據庫聲稱支援事務的操作,那麼該資料庫必須要具備以下四個特性: 1、原子性(Atomicity)   原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如

mysql資料庫事務型別

資料庫事務有不同的隔離級別,不同的隔離級別對鎖的使用是不同的,鎖的應用最終導致不同事務的隔離級別。隔離性分為四個級別: 1讀未提交:(Read Uncommitted) 2讀已提交(Read Committed) 大多數資料庫預設的隔離級別 3可重複讀(Repeatable-

MySQL 資料庫事務與複製

好久沒有寫技術文章了,因為一直在思考 「後端分散式」這個系列到底怎麼寫才合適。 最近基本想清楚了,「後端分散式」包括「分散式儲存」和 「分散式計算」兩大類。 結合實際工作中碰到的問題,以尋找答案的方式來剖解技術,很多時候我們都不是在創造新技術,

MySQL資料庫事務各隔離級別加鎖情況--read committed && MVCC

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

理解MySQL資料庫事務-隔離性

Transaction事務是指一個邏輯單元,執行一系列操作的SQL語句。 事務中一組的SQL語句,要麼全部執行,要麼全部回退。在Oracle資料庫中有個名字,叫做transaction ID 在關係型資料庫中,事務必須ACID的特性。 原子性,事務中的操作,要不全部執行,要不都不執行 一致性,事務完成前後,

MySQL(一):MySQL資料庫事務與鎖

#基本概念 事務是指滿足ACID特性的的一組操作,可以通過Commit提交事務,也可以也可以通過Rollback進行回滾。會存在中間態和一致性狀態(也是真正在資料庫表中存在的狀態) #ACID + **Atomicity【原子性】**:事務被視為不可分割的最小單元,事務的所有操作要麼全部提交成功,要麼全部失敗

SSM框架+MySQL資料庫配置事務管理

資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 例如銀行轉賬,A賬戶轉100元給B賬戶,正常的流程是A賬戶減掉100元,B賬戶增加100元。如果轉賬失敗的話,不能出現A賬戶已經減掉100元而B賬戶沒有增加10

【搞定MySQL資料庫】之事務的4種隔離級別詳解

資料庫事務的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事務的併發操作中可能會出現髒讀,不可重複讀,幻讀。下面通過事例一一闡述它們的概念與聯絡。 1、讀未提交