舉例說明MySQL中的事務
一.場景匯入
現在有一張倉庫表,倉庫表中記錄了每一個物品的數量,還有一張使用者表,使用者購買產品,倉庫表的產品數量減少,而使用者擁有產品的數量增加。
但是如果倉庫中的產品數量不足時怎麼處理?
例子:
#倉庫表 create table if not exists Warehouse( pro_id int primary key, pro_name varchar(10), pro_num int not null ); #使用者表,使用者表中的co_pro與倉庫表中pro_id為外來鍵關係 create table customer( co_name varchar(10), co_proint , co_pro_num int default -1, foreign key (co_pro) references warehouse(pro_id) );
倉庫表:使用者表:
建立一個購買的儲存過程後:
#購買商品儲存過程 delimiter // create procedure buy(in buy_num int) begin #首先將倉庫表中的數量減去 update warehouse set pro_num=pro_num-buy_num where pro_id = 100001; #增加使用者手裡的商品數目 update customer set co_pro_num=co_pro_num+buy_num where co_pro=100001; end //
在表面上似乎沒有問題,但是沒有考慮到情況當我倉庫中數目不足是怎麼辦?
例子:
call buy(11);
在這裡巧克力數目出現了負數,那麼這就是一個最基本的邏輯錯誤,想要避免這樣的錯誤就可以使用事務的回滾。
二.什麼是事務?
事務其實和儲存過程、儲存函式一樣也是一個sql語句的聚合體。
在這個聚合體中也是執行某個操作,但是這個操作將是一個整體,如果單元中某一條語句執行失敗了或者產生了錯誤,那麼將會將整個單元回滾,此前的執行操作將全部取消,資料庫將返回執行事務前的狀態。
四.事務的四個特徵
1.原子性
原子性理解就是:事務中的sql語句全部執行或者全部不執行。上面的例子中如果購買11個商品是不正確的那麼使用者也不會增加11個商品即增加的sql語句也不會執行即全部不執行,如果購買10個正確那麼就可以執行增加數量的sql語句即全部執行。
2.一致性
一致性理解就是:無論這個事物是否成功還是失敗,事務會使得資料庫處於一致狀態下,保持邏輯和資料的一致性。
比如說使用者購買10個巧克力成功時那麼使用者的資料庫中增加10個商品,而倉庫中的數量減少10個,失敗時回滾,回到購買前的資料狀態。這樣無論是在資料庫在成功還是失敗狀態下,邏輯和資料都是一致性的。
3.隔離性
多個事務在執行時他們是不能相互干擾的。
4.永久性
如果一個事務提交,那麼這個事務所造成的影響就就是永久的不可以在回滾的。
三.建立事務
3.1 MySQL中支援事務表的型別
在MySQL中支援事務表的型別有innoDB、BDB兩種。所以在建立表時要選擇表的型別。
3.2 建立一個事務
語法:start transaction; #初始化事務
事務主體
commit | rollback #提交事務或者回滾
下面我們將上一個儲存過程加上一個事務:
#購買商品儲存過程,使用事務 delimiter // create procedure buy(in buy_num int) begin declare pro_ture_num int default -1;#區域性變數獲得減去後的數量 #首先將倉庫表中的數量減去 start transaction;#開啟事務 update warehouse set pro_num=pro_num-buy_num where pro_id = 100001; set pro_ture_num=(select pro_num from warehouse where pro_id = 100001); if pro_ture_num >=0 then #增加使用者手裡的商品數目 update customer set co_pro_num=co_pro_num+buy_num where co_pro=100001; else rollback; end if; end //
來呼叫一下這個有事務的儲存過程:
測試1:
call buy(11);
結果:
測試2:
call buy(9);
結果