Skip to content

0402notes #27

@shiaoyi

Description

@shiaoyi

0402

NoSQL (Not Only SQL)

  • 沒有結構,把每筆資料存成一個json的樣子,可以有任意欄位、任意資料型態,沒有限制
  • 例子:MongoDB

Transaction 交易

想像成是一筆交易,例如轉帳
A 轉帳 20 塊給 B,要保證 A 少 20 塊的同時 B 多了 20 塊,兩者要同時成立,不能有一筆成功一筆失敗的問題

為了保證 Transaction 的正確性,要符合以下四個特性:

  1. 原子性 atomicity:要嘛全部失敗,要嘛全部成功
  2. 一致性 consistency:維持資料的一致性(錢的總數相同)
  3. 隔離性 isolation:多筆交易不會互相影響(不能同時改同一個值)
  4. 持久性 durability:交易成功之後,寫入的資料不會不見

在SQL裡用Transaction

$conn->autocommit(FALSE); // 如果沒有關掉,每執行一次query都會幫你commit一次,自己變成一個transaction
$conn->begin_transaction();
$conn->query("update from money set amount = 20");
$conn->query("update from money set sum = 10");
$conn->commit(); // 這裡才會真正commit,在這段程式之前的事都不算數,成功就會兩方一起成功,失敗就會一起失敗

phpmysql中的table裡有一型態欄,用來表示sql的引擎是哪一種,若為InnoDB則能支持transaction和lock,若為MyISAM則不支援

若多主機同時request,可能造成資源同時被取得,造成超賣的問題,必須用Lock解決

例如:網路搶購,幾乎同時三個人搶一個商品,造成本來剩一個的商品,數量變-2,導致超賣
使用Lock,會讓真正先來的request往下跑程式碼,後來的會先讓他等,等前一個跑完才能繼續往下跑

$conn->autocommit(FALSE);
$conn->begin_transaction();
$conn->query("SELECT amount from products where id = 1 for update"); //利用for update來先鎖上這行程式碼。記得打where,否則整個table都會被鎖起來
$conn->commit();

Lock要配合Transaction使用
缺點:因為要等待所以會造成效能上的損耗,若要一直等update,停在那邊不釋放的話,程式會整個當掉

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions