MySQL事務

2019-10-16 22:58:20

在本教學中,您將了解MySQL事務以及如何使用MySQL COMMIT語句和MySQL ROLLBACK語句來管理MySQL中的事務。

MySQL事務介紹

要了解MySQL中的事務是什麼,我們先來看看在範例資料庫(yiibaidb)中新增新的銷售訂單的範例。新增銷售訂單的步驟如下所述:

  • orders表中查詢最新的銷售訂單編號,並使用下一個銷售訂單編號作為新的銷售訂單編號。
  • 在指定客戶的orders表中插入新的銷售訂單。
  • 將新的銷售訂單專案插入orderdetails表中。
  • orders表和orderdetails中獲取資料以確認更改。

現在想象如果由於資料庫故障而導致上述一個或多個步驟失敗,那麼資料會發生什麼? 如果將訂單項新增到orderdetails表中的步驟失敗,系統中將會有空的銷售訂單(只有訂單號,不知道這個訂單賣了什麼)。資料可能不完整,那麼必須花費的精力來解決這個問題。

如何解決這個問題? 這就是為什麼事務來處理。 MySQL事務使您能夠執行一組MySQL操作,以確保資料庫從不包含部分操作的結果。 在一組操作中,如果其中一個失敗,則會恢復回滾資料庫。 如果沒有發生錯誤,則將整個語句集合提交到資料庫。

使用MySQL事務

在上述範例中,我們將使用它們新增銷售訂單之前,先來看看MySQL事務語句。

要啟動事務,請使用START TRANSACTION語句。要撤消MySQL語句執行,請使用ROLLBACK語句。

請注意,有一些SQL語句,主要是資料定義語句,不能在事務中使用以下語句:

CREATE / ALTER / DROP DATABASE
CREATE /ALTER / DROP / RENAME / TRUNCATE TABLE
CREATE / DROP INDEX
CREATE / DROP EVENT
CREATE / DROP FUNCTION
CREATE / DROP PROCEDURE
…

要將更改寫入事務中的資料庫,請使用COMMIT語句。要注意的是,預設情況下,MySQL自動提交對資料庫的更改。

要強制MySQL不會自動提交更改,請使用以下語句:

SET autocommit = 0

MySQL事務的例子

要使用MySQL事務,首先必須將MySQL語句分解成邏輯部分,並確定何時應該提交或回滾資料。

下面來看一下使用MySQL事務在上面的範例資料庫中新增新的銷售訂單並新增事務處理步驟的例子:

  • 使用START TRANSACTION語句啟動事務。
  • orders表中獲取最新的銷售訂單編號,並使用下一個銷售訂單編號作為新的銷售訂單編號。
  • 在指定orders表中插入新的銷售訂單。
  • 將新的銷售訂單專案插入orderdetails表中。
  • 使用COMMIT語句提交更改。
  • orders表和orderdetails表中獲取資料以確認更改。

以下是執行上述步驟的指令碼:

-- start a new transaction
start transaction;

-- get latest order number
select @orderNumber := max(orderNUmber) 
from orders;
-- set new order number
set @orderNumber = @orderNumber  + 1;

-- insert a new order for customer 145
insert into orders(orderNumber,
                   orderDate,
                   requiredDate,
                   shippedDate,
                   status,
                   customerNumber)
values(@orderNumber,
       now(),
       date_add(now(), INTERVAL 5 DAY),
       date_add(now(), INTERVAL 2 DAY),
       'In Process',
        145);
-- insert 2 order line items
insert into orderdetails(orderNumber,
                         productCode,
                         quantityOrdered,
                         priceEach,
                         orderLineNumber)
values(@orderNumber,'S18_1749', 30, '136', 1),
      (@orderNumber,'S18_2248', 50, '55.09', 2); 
-- commit changes    
commit;       

-- get the new inserted order
select * from orders a 
inner join orderdetails b on a.ordernumber = b.ordernumber
where a.ordernumber = @ordernumber;

在本教學中,您學習了如何使用START TRANSACTION COMMIROLLBACK的MySQL事務語句來管理MySQL中的事務以保護資料完整性。