iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Modern Web

MySQL,我的超人系列 第 12

Day12-MySQL的交易(Transactions)

  • 分享至 

  • xImage
  •  

ACID

在進入交易Transactions之前,必須先理解ACID的概念

1.Atomicity,原子性,所有的SQL語句都是不可分割的個體,只要其中一句失敗,交易就會被復原
2.Consistency,一致性,資料庫始終保持一致性,舉例來說不會出現交易後,發現某張訂單少了價格或是數量
3.Isolation,隔離性,交易彼此之間相互隔離,受影響的行在交易發生會上鎖,其他交易必須等其完成才能執行
4.Durability,持久性,一旦交易被提交(COMMIT),就算電腦當機、或是系統崩潰都不會影響結果

https://ithelp.ithome.com.tw/upload/images/20220926/20144865WuUj5xoFNg.jpg

看完以上四點,大概可以理解交易的基本性質,只會出現兩種結果,成功提交或是失敗回滾(ROLLBACK),交易的應用非常多,以下舉2個常見的例子

1.銀行轉帳,轉帳一定分成至少兩個步驟,首先是轉帳者的帳戶扣款,其次是被轉帳者的帳戶進帳,其中只要一個步驟失敗,整個交易就會回復到還沒發生過的狀態

2.商品訂單,當消費者點選確定結帳後,大多數的情況都會成立一筆訂單,基於資料庫的正規化,訂單明細會放在另外一張表,所以同樣是必須先插入一行訂單再插入訂單明細,假設不使用交易的寫法,就會發生悲劇

小明在網路上買了10隻筆,但是負責電商後台的工程師因為沒喝咖啡導致想睡覺,忘記使用交易就直接插入資料庫,好巧不巧伺服器又突然當機,就會發生以下的悲劇

https://ithelp.ithome.com.tw/upload/images/20220926/201448659GJoR93e6x.jpg

為了方便舉例,SQL使用分級插入裡的範例

INSERT INTO orders (order_id, name, order_date,comments) -- 插入一筆剛成立的訂單
VALUES (default, '小明','2019-01-01', 'good');

-- 伺服器突然掛了,以下語句無法執行

INSERT INTO order_details  -- 消失的訂單明細
VALUES 
    (default, 1, 10, 10),
    (default, 2, 10, 10),
    (default, 3, 10, 10);
    

結果就會變成有一筆訂單對應不到訂單明細,其實這是蠻嚴重的問題,不過使用交易也不代表從此萬無一失,可能因為錯誤的使用導致死鎖的發生,過度的使用也可能導致效能下降的問題。

https://ithelp.ithome.com.tw/upload/images/20220926/20144865VWvxcmnj30.jpg

START TRANSACTION;

INSERT INTO orders (order_id, name, order_date,comments)
VALUES (default, '小明','2019-01-01', 'good');

INSERT INTO order_details
VALUES 
    (default, 1, 10, 10),
    (default, 2, 10, 10),
    (default, 3, 10, 10);
COMMIT;

預告

Day13-MySQL的併發(Concurrency)


上一篇
Day11-MySQL的事件(Events)
下一篇
Day13-MySQL的併發(Concurrency)-髒讀、更新丟失、幻讀、不可重複讀
系列文
MySQL,我的超人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言