前面 實作練習 使用了Trigger、Stored Procedure、Stored Function來完成訂單的處理,但是在處理的過程中沒有加入「錯誤處理」,也就是當發生錯誤時應該怎麼處理。 在資料庫操作中,錯誤處理是一個非常重要的部分,它確保當操作失敗或發生異常時,系統能夠優雅地應對並保護資料完整性和一致性。錯誤處理的主要目的是識別錯誤、記錄錯誤資訊、進行必要的補救措施(如Rollback),並將錯誤訊息適當地傳達給使用者或系統管理員。 錯誤處理的語法 : DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- 錯誤處理程序 -- 這裡加入需要的邏輯 END; (1) Stored Procedure 處理錯誤 : -- 建立一個資料表Products : CREATE TABLE Products ( ProductID INT AUTO_INCREMENT PRIMARY KEY, ProductName VARCHAR(100) NOT NULL, Price DECIMAL(10, 2) NOT NULL, Stock INT NOT NULL ); -- 建立一個資料表ProductLogs : CREATE TABLE P…
現在要來做個實作練習 : 建立 Trigger 可以自動減去訂單數量,用來維護庫存量;然後建立 Stored Procedure 用來建立訂單,並建立 Trigger 用來記錄建立訂單的log;建立 Stored Function 用來計算訂單總額,並以php呼叫Stored Procedure 以介面來輸入訂單資料。 要達成以上的需求,我們可以怎麼做呢? (1) 建立 MySQL 資料庫 : CREATE DATABASE OrderSystem CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 然後進入該資料庫 : USE OrderSystem; (2) 建立各資料表格 -- 接著建立商品資料表格Products : CREATE TABLE Products ( ProductID INT AUTO_INCREMENT PRIMARY KEY, ProductName VARCHAR(100) NOT NULL, Price DECIMAL(10, 2) NOT NULL, Stock INT NOT NULL ); -- 建立訂單資料表格Orders : CREATE TABLE Or…
觸發器 (Trigger) 是一種自動執行的程式,它會在表格上執行指定的INSERT、UPDATE或DELETE操作時被觸發。觸發器可以用來自動執行一些維護數據一致性的任務,例如驗證數據、記錄變更日誌等。 範例 : 如何在XAMPP中使用MySQL Trigger (範例) MySQL Stored Procedure/Stored Function/Trigger 實作 : 工讀生薪資管理系統 Trigger的語法 在MySQL中創建Trigger的語法如下: CREATE TRIGGER trigger_name {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name FOR EACH ROW BEGIN -- 觸發器執行的SQL語句 statement1; statement2; statement3; END; trigger_name:觸發器的名稱。 BEFORE | AFTER:指定觸發器是在操作前還是操作後執行。 INSERT | UPDATE | DELETE:指定觸發器的觸發事件類型。 table_name:觸發器所關聯的表名。 FOR EACH ROW:指定觸發器…
在解釋 Isolation Level 隔離層級之前,先說明三個名詞 : 髒讀 (dirty read)、幻讀 (phantom read)、不可重複讀 (Non-Repeatable Read)。 髒讀 (dirty read) : 指在一個交易讀取到另一個尚未提交 (un-commit) 的交易資料。如果那個交易最終被回滾(Rollback),則讀到的資料就是不準確的,這就是所謂的「髒讀」。 髒讀就像做夢撿到錢,結果醒來什麼都沒有。 幻讀 (phantom read) : 指在一個交易中,當它多次執行同一查詢時,由於其他交易插入、更新或刪除了符合查詢條件的行,導致每次查詢返回的結果不同。 幻讀就像見到鬼,資料多了或是少了。 不可重複讀 (Non-Repeatable Read) : 指在一個交易在多次讀取同一筆資料時,該資料的值因為另一個交易的更新而發生變化。 不可重複讀就像碰到魔術師,明明手上是棍子,等一下 變成鴿子。 髒讀、幻讀、不可重複讀都不是正常的現象,除非有特別的目的,不然都應該盡量避免。 隔離層級是什麼? 隔離層級(Isolation Level)是資料庫管理系統中設定交易(Transaction)之間互相隔離程度的配置選項。它控制了在多個交易並發 (concur…
在之前的文章已經談過很多關於MySQL 資料庫鎖定 的觀念及實作,這篇把所有的觀念一次整合在一起,也比較容易完全理解MySQL的鎖定如何應用在實際的系統設計上。 鎖定的定義 : 在 MySQL 中,資料庫的鎖定是一種用於管理多用戶或程序同時訪問同一資料庫資源時的同步機制。鎖定可以幫助預防資料不一致和更新衝突,保護交易的完整性。 既然是鎖定,當然就會讓某一方等待,如果鎖得不好,就會發生死鎖 (deadlock)。 因此鎖定就是為了達成資料的一致性及完整性,犧牲某些效率的做法。你不可能既要資料的一致性及完整性,又要求任何連線都不能等待。在非常大量連線的情況下,這些等待都可能造成程式超時 (timeout) 。 例如php程式的預設超時 (default timeout) 是30秒,MySQL的預設鎖定等待超時 (lock wait timeout)是50秒,如果因為等待而超過,程式就會停止並顯示錯誤訊息。如果拉長預設超時,當遇到死鎖或是大家都在等待,就更可能吃光系統的資源,讓正在執行的更緩慢。 因此,多人連線的系統,正確的處理交易以及正確的使用鎖定是很重要的,並且正確性與效能是同樣重要的事情。 有些系統效能比正確性還重要 (例如臉書的數據處理),有些系統正確性比效能還重要 (例如銀…
什麼是交易(Transaction 很多人稱為事務)功能? 交易(或事務)指的是一連串的指令,並且把它們作為一個單一的工作單位執行。這些操作要嘛全部執行,要嘛全部取消。 交易主要用於保證資料的一致性和完整性,特別是在多用戶環境中,其中多個操作可能同時對相同的資料進行讀寫。 例如一個訂單的完成,包含「將庫存資料表的數量更新」,然後「將訂購的商品資料寫入訂單資料表」。 這兩個動作如果不是都完成,就會產生問題。例如庫存資料表的數量已經-1,但是訂單資料沒有寫入,那麼庫存數量就發生錯誤了;或是訂單資料已經寫入,但是庫存的數量-1發生錯誤,這樣也會發生資料一致性的問題。 例如以下的PHP程式 order.php : <?php include 'conn.inc.php' ; // 引入連線設定檔 // 從 myproducts 表抓取產品 $query = "SELECT pid, pname FROM myproducts" ; $result = $conn ->query( $query ); // 檢查訂購按鈕是否被點擊 if ( $_SERVER [ "REQUEST_METHOD" ] == &qu…