1. 程式人生 > 實用技巧 >MySQL資料庫之事務

MySQL資料庫之事務

事務

  • 概述

    • 事務(TRANSACTION)是一個整體,要麼一起執行,要麼一起不執行
  • 事務特性:事務必須具備以下四個屬性,簡稱ACID 屬性

    • 原子性(Atomicity)
      • 事務是一個完整的操作
      • 事務的各步操作是不可分的(原子的)
      • 要麼都執行,要麼都不執行
    • 一致性(Consistency)
      • 當事務完成時,資料必須處於一致狀態
    • 隔離性(Isolation)
      • 對資料進行修改的所有併發事務是彼此隔離的
    • 永久性(Durability)
      • 事務完成後,它對資料庫的修改被永久保持

更改定界符 delimiter

  • 一般情況下的定界符

    • 其實就是告訴mysql直譯器,該段命令是否已經結束了,mysql是否可以執行了
    • 預設情況下,delimiter是分號;
    • 在命令列客戶端中,如果有一行命令以分號結束,那麼回車後,mysql將會執行該命令
  • 可能輸入較多的語句,且語句中包含有分號時的定界符設定

    • 預設情況下,不可能等到使用者把這些語句全部輸入完之後,再執行整段語句
    • 因為mysql一遇到分號,它就要自動執行
    • 這種情況下,就需要事先把delimiter換成其它符號,如//或$$
MariaDB [sel]> create table bank(
    -> card char(4) primary key comment '卡號',
    -> money decimal(10,2) not null
    -> )charset=utf8;
# `Query OK, 0 rows affected (0.023 sec)`

MariaDB [sel]> insert into bank values ('1001',1000),('1002',10);
# `Query OK, 2 rows affected (0.012 sec)`
# `Records: 2  Duplicates: 0  Warnings: 0`

MariaDB [sel]> begin;
# `Query OK, 0 rows affected (0.000 sec)`

MariaDB [sel]> delimiter //
MariaDB [sel]> update bank set money=money-100 where card='1001';
    -> update bank set money=money+90 where card='1002'//
# `Query OK, 1 row affected (0.008 sec)`
# `Rows matched: 1  Changed: 1  Warnings: 0`

Query OK, 1 row affected (0.008 sec)
# `Rows matched: 1  Changed: 1  Warnings: 0`

MariaDB [sel]> rollback //
# `Query OK, 0 rows affected (0.008 sec)`

MariaDB [sel]> select * from bank //
+------+---------+
| card | money   |
+------+---------+
| 1001 | 1000.00 |
| 1002 |   10.00 |
+------+---------+
# `2 rows in set (0.000 sec)`

事務處理

  • 相關指令

    • 開啟事務 start transactionbegin [work]
    • 提交事務 commit
    • 回滾事件 rollback
    • 記錄事務的回滾點 savepoint 錨點
  • 自動提交事務

    • 每一個SQL語句都是一個獨立的事務
  • 事務生命週期

    • 事務是事務開啟的時候開始
    • 提交事務、回滾事務後事務都結束
    • 只有innodb支援事務
    • 一個SQL語句就是一個獨立的事務,開啟事務是將多個SQL語句放到一個事務中執行

事務處理提交

MariaDB [sel]> start transaction //
# `Query OK, 0 rows affected (0.000 sec)`

MariaDB [sel]> update bank set money=money-100 where card='1001';
    -> update bank set money=money+90 where card='1002'//
# `Query OK, 1 row affected (0.007 sec)`
# `Rows matched: 1  Changed: 1  Warnings: 0`

# `Query OK, 1 row affected (0.008 sec)`
# `Rows matched: 1  Changed: 1  Warnings: 0`

MariaDB [sel]> commit //
# `Query OK, 0 rows affected (0.008 sec)`

MariaDB [sel]> select * from bank //
+------+--------+
| card | money  |
+------+--------+
| 1001 | 900.00 |
| 1002 | 100.00 |
+------+--------+
# `2 rows in set (0.000 sec)`

事務處理回滾

MariaDB [sel]> begin //
# `Query OK, 0 rows affected (0.000 sec)`

MariaDB [sel]> insert into bank values ('1003',500) //
# `Query OK, 1 row affected (0.007 sec)`

MariaDB [sel]> savepoint a1 //
# `Query OK, 0 rows affected (0.000 sec)`

MariaDB [sel]> insert into bank values ('1004',500) //
# `Query OK, 1 row affected (0.000 sec)`

MariaDB [sel]> rollback to a1 //
# `Query OK, 0 rows affected (0.000 sec)`

MariaDB [sel]> select * from bank //
+------+--------+
| card | money  |
+------+--------+
| 1001 | 900.00 |
| 1002 | 100.00 |
| 1003 | 500.00 |
+------+--------+
# `3 rows in set (0.000 sec)`