天天看點

CI架構百問百答:CodeIgniter的事務用法?--第9問

做為一名碼工,沒用過事務,那也不是好碼工。

CodeIgniter的資料庫抽象允許你在支援事務安全的資料庫表中使用事務。在MySQL中,你需要用InnoDB或BDB表而不是更常用的MyISAM。大多數其它的資料庫平台都原生支援事務。

一起看看CodeIgniter的事務:

CodeIgniter 的事務方法

CodeIgniter 使用的事務方法與流行的資料庫類ADODB所使用的處理過程非常相似。我們選擇那種方法是因為它極大地簡化了運作事務的處理過程。大多數情況下你隻需要編寫兩行代碼就行了。

傳統上, 事務需要實作大量工作, 他們要求你随時跟蹤你的查詢, 并根據查詢的成功或失敗來決定 送出 還是 復原。這是特别麻煩的嵌套查詢。相比之下, 我們實作了一種智能的事務系統, 它将自動地為你做這些事情(如果你選擇手動管理你的事務, 這也是可以的, 但這确實沒什麼好處)。

運作事務

要使用事務來運作你的查詢, 你可以使用如下所述的 $this->db->trans_start() 和 $this->db->trans_complete() 函數:

$this->db->trans_start(); $this->db->query('一條SQL查詢...'); $this->db->query('另一條查詢...'); $this->db->query('還有一條查詢...'); $this->db->trans_complete();

在 start/complete 函數之間, 你想運作多少條查詢都可以, 根據任何給定查詢的成功或失敗, 它們将被送出或者復原。

嚴格模式(Strict Mode)

預設情況下, CodeIgniter 以嚴格模式運作所有事務。當嚴格模式被啟用時, 如果你正在運作多組的事務, 隻要有一組失敗, 所有組都會被復原。如果嚴格模式被禁用, 每一組都被視為獨立的組, 這意味着其中一個組的失敗不會影響其它組。

嚴格模式能以下面的方式禁用:

$this->db->trans_strict(FALSE);

管理錯誤資訊

如果你在你的 config/database.php 檔案中啟用了錯誤報告, 當送出沒有成功時, 你會看到一條标準的錯誤資訊。如果調試被關閉, 你可以通過這種方式來管理你的錯誤資訊:

$this->db->trans_start(); $this->db->query('AN SQL QUERY...'); $this->db->query('ANOTHER QUERY...'); $this->db->trans_complete(); if ($this->db->trans_status() === FALSE) {     // 生成一條錯誤資訊... 或者使用 log_message() 函數來記錄你的錯誤資訊 }

禁用事務

當你使用 $this->db->trans_start() 時, 事務就已經被自動啟用了。如果你想要禁用事務, 你可以使用 $this->db->trans_off() 來實作:

$this->db->trans_off() $this->db->trans_start(); $this->db->query('AN SQL QUERY...'); $this->db->trans_complete();

當事務被禁用的時候, 你的查詢将被自動送出, 就像沒有使用事務時那樣。

測試模式(Test Mode)

你可以選擇性地将事務系統設定到 "測試模式" , 這将導緻你的查詢被復原 -- 盡管查詢會生成有效結果。要使用測試模式, 隻需将 $this->db->trans_start() 函數的第一個參數設定為 TRUE 即可:

$this->db->trans_start(TRUE); // 查詢将被復原 $this->db->query('AN SQL QUERY...'); $this->db->trans_complete();

手動運作事務

如果你想要手動運作事務, 可以使用下面的方法:

$this->db->trans_begin(); $this->db->query('AN SQL QUERY...'); $this->db->query('ANOTHER QUERY...'); $this->db->query('AND YET ANOTHER QUERY...'); if ($this->db->trans_status() === FALSE) {     $this->db->trans_rollback(); } else {     $this->db->trans_commit(); }

說明: 手動運作事務時, 請務必使用 $this->db->trans_begin() 函數, 而不是 $this->db->trans_start().