1. 程式人生 > >管理事務處理

管理事務處理

1.什麼是事務管理

  • 可以把一系列要執行的操作稱為事務,而事務管理就是管理這些操作要麼完全執行,要麼完全不執行(很經典的一個例子是:A要給B轉錢,首先A的錢減少了,但是突然的資料庫斷電了,導致無法給B加錢,然後由於丟失資料,B不承認收到A的錢;在這裡事務就是確保加錢和減錢兩個都完全執行或完全不執行,如果加錢失敗,那麼不會發生減錢)。

  • 事務管理的意義:保證資料操作的完整性。

  • mysql中並不是所有的資料引擎都支援事務管理的,只有innodb支援事務管理。

    事務管理的特性:

    • 原子性:事務的整個操作是一個整體,不可以分割,要麼全部成功,要麼全部失敗。
    • 一致性:事務操作的前後,資料表中的資料沒有變化。
    • 隔離性:事務操作是相互隔離不受影響的。
    • 永續性:資料一旦提交,不可改變,永久的改變資料表資料。

2.事務管理操作

  • 開啟事務管理:開啟之後,下面的sql語句並不會馬上執行並把結果寫到表中,而是會寫到事務日誌中。
    • start transaction;
  • 回退操作:回退會清掉開始事務管理之後寫到事務日誌中的內容,即恢復到開啟事務管理之前。
    • 語法:rollback;
    • 注意:回退操作只是回退"寫"的內容,對於普通的讀表select語句不能回退。
  • 事務提交:將sql語句的結果寫到資料表中。
    • 語法:commit:

實驗表:

create table bankaccount(id int primary key auto_increment,name varchar(15),money int);
insert into bankaccount(name,money) values("Jobs",2000);
insert into bankaccount(name,money) values("Bill",3000);
mysql> start transaction;
Query OK, 0 rows affected

mysql> update bankaccount set money=money - 1000 where name = 'Bill';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0
-- 更改沒有生效
mysql> 
mysql> update bankaccount set money=money + 1000 where name = 'Jobs';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0
-- 更改生效
mysql> commit;
Query OK, 0 rows affected
mysql> select * from bankaccount;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | Jobs |  3000 |
|  2 | Bill |  1000 |
+----+------+-------+
2 rows in set
-- 開啟事務
mysql> start transaction;
Query OK, 0 rows affected

mysql> update bankaccount set money=money - 1000 where name = 'Jobs';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update bankaccount set money=money + 1000 where name = 'Bill';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0
-- 回滾,執行不生效
mysql> rollback;
Query OK, 0 rows affected

mysql> select * from bankaccount;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | Jobs |  3000 |
|  2 | Bill |  1000 |
+----+------+-------+
2 rows in set

補充:

  • 當 commit 或 rollback 語句執行後,事務會自動關閉(將來的更改會隱含提交)。
  • 鎖機制:在事務操作一個表時,如果使用索引來取值,那麼會鎖定到對應行;如果沒有使用索引來取值,那麼會鎖定整個表。鎖定之後其他連線無法操作指定行或表。

3.回滾點

  • 回滾點可以指定rollback回退的位置【比如現在打了100條命令,發現第81打錯了,如果回滾到打了81命令之前一點而不是回滾到開啟事務之前就可以節省下很多時間。】
  • 語法:
    • 建立回滾點:savepoint 回滾點名;
    • 回滾到回滾點:rollback to 回滾點名;
mysql> start transaction;
Query OK, 0 rows affected

mysql> savepoint before_bank;
Query OK, 0 rows affected

mysql> update bankaccount set money=money - 1000 where name = 'Jobs';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update bankaccount set money=money + 1000 where name = 'Bill';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> rollback to before_bank;
Query OK, 0 rows affected

mysql> update bankaccount set money=money - 500 where name = 'Jobs';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update bankaccount set money=money + 500 where name = 'Bill';
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected

mysql> select * from bankaccount;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | Jobs |  2500 |
|  2 | Bill |  1500 |
+----+------+-------+
2 rows in set

補充:

  • 回滾點在事務管理關閉(rollback或commit之後)之後失效,不要在事務之外使用回滾點。

4.預設的事務管理

  • 預設情況下,mysql的事務管理是關閉(自動事務)的,語句的結果會馬上寫到資料表中。

    • 可以通過show variables like ‘autocommit’;來檢視是否開啟自動事務,值為ON為自動事務已開啟,為OFF則為關閉。

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

  • 關閉自動事務:set autocommit =0;【關閉後需要commit來執行每一條語句,相當於開始了事務管理】

    • 不過注意的是set autocommit針對的是會話變數,所以這個設定只在此次會話連線中生效。
  • mysql> show variables like 'autocommit';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | autocommit    | ON    |
    +---------------+-------+
    1 row in set
    
    mysql> set autocommit =0;
    Query OK, 0 rows affected
    
    mysql> show variables like 'autocommit';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | autocommit    | OFF   |
    +---------------+-------+
    1 row in set
    
    mysql> set autocommit = 1;
    Query OK, 0 rows affected
    
    mysql> show variables like 'autocommit';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | autocommit    | ON    |
    +---------------+-------+
    1 row in set