天天看點

詳解MariaDB資料庫的事務

1.什麼是事務

資料庫事務:(database transaction): 事務是由一組SQL語句組成的邏輯處理單元,一組事務中的SQL語句要不全部執行成功功;如果其中某一條執行失敗,則這組SQL語句中已經執行的語句會復原到這組SQL語句執行之前的狀态。

事務處理,可以確定非事務性單元的多個操作都能成功完成,否則不會更新資料資源。

資料庫預設事務是自動送出的, 也就是發一條 sql 它就執行一條。如果想多條 sql 放在一個事務中執行,則需要使用事務進行處理。

當我們開啟一個事務,并且沒有送出,可以使用 rollback 指令手動復原事務。

優點:

通過将一組操作組成一個事務執行時,要麼全部成功,要麼全部失敗的單元。
使程式更可靠,簡化錯誤恢複。
           

例如,A使用者給B使用者轉賬1000元,此時表現在SQL語句上,就是先更新A賬戶在的餘額,減去1000,然後再更新B賬戶的餘額,加上1000。以上操作對應資料庫為兩個update操作,這兩個操作屬于一個事物。否則,萬一當資料庫在減去A賬戶上的錢,而還沒來得及在B賬戶加上1000時,資料庫出現故障,此時就會出現這1000元錢消失的悲劇,這時資料庫的事務就派上用場了。

2. 事務四大特性

事務是必須滿足4個條件(ACID):

2.1 原子性(Autmic)

事務在執行時,要做到“要麼不做,要麼全做!”,就是說不允許事務隻執行其中一部分。
即使因為故障而使事務不能完成,在rollback時也要消除對資料庫的影響。
           

2.2 一緻性(Consistency)

事務必須是使資料庫從一個一緻性狀态變到另一個一緻性狀态。一緻性與原子性是密切相關的。
在事務開始之前和結束之後,資料庫的完整性限制沒有被破壞
           

2.3 隔離性(Isolation)

一個事務的執行不能被其他事務幹擾。
即一個事務内部的操作及使用的資料對并發的其他事務是隔離的,并發執行的各個事務之間不能互相幹擾,這些通過鎖來實作。
           

2.4 持久性(Durability)

指一個事務一旦送出,它對資料庫中資料的改變就應該是永久性的。
接下來的其他操作或故障(比如說當機等)不應該對其有任何影響。
           

事務的ACID特性可以確定銀行不會弄丢你的錢。而在應用邏輯中,要實作這點非常難,甚至可以說是不可能完成的任務。

3. MySQL事務的使用方法

3.1 用BEGIN,ROLLBACK,COMMIT來實作

START TRANSACTION | BEGIN [WORK]  開啟事務
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] 送出目前事務,執行永久操作。
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] 復原目前事務到開始點,取消上一次開始點後的所有操作。
SAVEPOINT 名稱 折返點
           

3.2 直接用 SET AUTOCOMMIT 來改變mysql的自動送出模式

MySQL/MariaDB資料庫預設是自動送出的,也就是你送出一組SQL語句,資料庫就會立即執行。
此時可以使用`SET AUTOCOMMIT`指令來設定事務是否自動送出。
SET AUTOCOMMIT預設是自動送出的。
           

SET AUTOCOMMIT指令文法:

SET AUTOCOMMIT = {0 | 1}
           

SET AUTOCOMMIT指令的值的設定解析

0:禁止自動送出
1:開啟自動送出。
           
需要注意的是,MySQL/MariaDB中隻有INNODB和BDB類型的資料表才能支援事務處理!另外一種常用的資料庫引擎MyISAM是不支援事務操作的。

例子:

MariaDB [book]> set autocommit = 0;				# 設定資料庫關閉自動送出
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter //					# 修改SQL語句的結束符為'//'
MariaDB [book]> start transaction;					# 定義一組事務操作語句
    -> update books set bName="ccc" where bId=1;	# 把bId等于1的books表的記錄的bName改為'ccc'
    -> update books set bName="ddd" where bId=2;	# 把bId等于2的books表的記錄的bName改為'ddd'
    -> commit;//
Query OK, 0 rows affected (0.01 sec)

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;						# 把sql語句的結束标志重新改回';'
MariaDB [book]> select bName from books where bId=1 or bId=2;	# 查找books表中bId等于1或2的所有記錄的bName字段資訊
+-------+
| bName |
+-------+
| ccc   |
| ddd   |
+-------+
2 rows in set (0.00 sec)

MariaDB [book]> show create table books\G		# 檢視books表的建立資訊,可以看出books表使用MyISAM資料引擎,MyISAM引擎不支援事務操作,是以要到books表的引擎改為InnoDB
*************************** 1. row ***************************
       Table: books
Create Table: CREATE TABLE `books` (
  `bId` int(4) NOT NULL AUTO_INCREMENT,
  `bName` varchar(255) DEFAULT NULL,
  `bTypeId` enum('1','2','3','4','5','6','7','8','9','10') DEFAULT NULL,
  `publishing` varchar(255) DEFAULT NULL,
  `price` int(4) DEFAULT NULL,
  `pubDate` date DEFAULT NULL,
  `author` varchar(30) DEFAULT NULL,
  `ISBN` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`bId`),
  FULLTEXT KEY `index_bName` (`publishing`)
) ENGINE=MyISAM AUTO_INCREMENT=45 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

MariaDB [book]> alter table category engine=innodb;		# 修改category資料表的引擎為InnoDB
Query OK, 9 rows affected (0.03 sec)               
Records: 9  Duplicates: 0  Warnings: 0

MariaDB [book]> alter table books engine=innodb;		# 修改books資料表的引擎為InnoDB
Query OK, 39 rows affected (0.02 sec)              
Records: 39  Duplicates: 0  Warnings: 0

MariaDB [book]> show create table books;				# 檢視books資料表的建立資訊,可以看到books表已經使用InnoDB引擎了
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                               |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| books | CREATE TABLE `books` (
  `bId` int(4) NOT NULL AUTO_INCREMENT,
  `bName` varchar(255) DEFAULT NULL,
  `bTypeId` enum('1','2','3','4','5','6','7','8','9','10') DEFAULT NULL,
  `publishing` varchar(255) DEFAULT NULL,
  `price` int(4) DEFAULT NULL,
  `pubDate` date DEFAULT NULL,
  `author` varchar(30) DEFAULT NULL,
  `ISBN` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`bId`)
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)

MariaDB [book]> show create table category;				# 檢視category資料表,category資料表也已經使用InnoDB引擎了
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                    |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| category | CREATE TABLE `category` (
  `bTypeId` int(4) NOT NULL AUTO_INCREMENT,
  `bTypeName` varchar(40) DEFAULT NULL,
  PRIMARY KEY (`bTypeId`),
  KEY `bTypeName` (`bTypeName`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

MariaDB [book]> set autocommit = 0;						# 設定資料表不自動送出
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter //							# 把sql語句的結束符更改為'//'
MariaDB [book]> start transaction;						# 定義一組事務操作語句
    -> update books set bName="book1" where bId=1;		# 把books資料表中bId為1的記錄的bName字段改為'book1'
    -> update books set bName="book2" where bId=2;		# 把books資料表中bId為2的記錄的bName字段改為'book2'
    -> commit//											# 使用commit送出更改,此時整個事務操作已經完成,不能復原到update之前的狀态了
Query OK, 0 rows affected (0.01 sec)

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 0 rows affected (0.03 sec)

MariaDB [book]> delimiter ;								# 把sql語句的結束符改回';'
MariaDB [book]> select bName from books where bId=1 or bId=2;		# 查詢books資料表中bId為1或2的記錄的bName字段資訊
+-------+
| bName |
+-------+
| book1 |
| book2 |
+-------+
2 rows in set (0.00 sec)

MariaDB [book]> delimiter //					# 把sql語句的結束符更改為'//'
MariaDB [book]> start transaction;				# 定義一組事務操作語句
    -> update books set bName = "name1";		# 把books資料庫中所有bName字段更新為'name1'
    -> //
Query OK, 0 rows affected (0.01 sec)

Query OK, 39 rows affected (0.01 sec)
Rows matched: 39  Changed: 39  Warnings: 0

MariaDB [book]> select bName from books;		# 檢視books資料表中所有記錄的bName字段資訊
    -> //
+-------+
| bName |
+-------+
| name1 |
| name1 |
| name1 |
| name1 |
| name1 |
| name1 |
| name1 |
+-------+
39 rows in set (0.01 sec)
	
MariaDB [book]> rollback//						# 使用rollback進行復原操作,由于在前面設定了不自動送出,是以可以復原成功
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> select bName from books//		# 查詢books資料表中所有記錄的bName字段資訊
+---------------------------------------------------------+
| bName                                                   |
+---------------------------------------------------------+
| book1                                                   |
| book2                                                   |
| 網絡程式與設計-asp                                     |
| pagemaker 7.0短期教育訓練教程                               |
| 黑客攻擊防範秘笈                                        |
| Dreamweaver 4入門與提高                                 |
| 網頁樣式設計-CSS                                       |
| Internet操作技術                                        |
| Dreamweaver 4網頁制作                                   |
| Auto CAD職業技能教育訓練教程                                |
| Fireworks 4網頁圖形制作                                 |
| 自己動手建立企業區域網路                                  |
| 頁面特效精彩執行個體制作                                    |
| 平面設計制作整合案例詳解-頁面設計卷                    |
| Illustrator 10完全手冊                                  |
| FreeHand 10基礎教程                                     |
| 網站設計全程教程                                        |
| 動态頁面技術-HTML 4.0使用詳解                          |
| Auto CAD 3D模型大師                                     |
| Linux傻瓜書                                             |
| 網頁界面設計藝術教程                                    |
| Flash MX 标準教程                                       |
| Auto CAD 2000 應用及執行個體基集錦                          |
| MySQL                                                   |
| ASP資料庫系統開發執行個體導航                               |
| Delphi 5程式設計與控件參考                              |
| 活學活用Delphi5                                         |
| Auto CAD 2002 中文版實用教程                            |
| 精通Javascript                                          |
| 深入Flash 5教程                                         |
| Auto CAD R14 中文版實用教程                             |
| Frontpage 2000& ASP 網頁設計技巧與網站維護             |
| HTML設計實務                                            |
| Javascript與Jscript從入門到精通                         |
| lllustrator 9寶典                                       |
| MySQL                                                   |
| MySQL                                                   |
| ASP 3初級教程                                           |
| XML 完全探索                                            |
+---------------------------------------------------------+
39 rows in set (0.00 sec)