1. 程式人生 > >舉例說明MySQL中的事務

舉例說明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_pro 
int , 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中支援事務表的型別有innoDBBDB兩種。所以在建立表時要選擇表的型別。

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);

結果