2010-02-28 31 views

回答

9

你可以做這樣的事情:

mysqli_autocommit($dbconn, FALSE); 

$errors = array(); 

if (!$mysqli->query(/* some SQL query */)) { 
    $errors[] = $mysqli->error; 
} 
// ... more queries like the above 
if(count($errors) === 0) { 
    $mysqli->commit() 
} else { 
    $mysqli->rollback(); 
    print_r($errors); 
} 

當查詢出錯,將錯誤添加到$ errors數組,這樣你就會知道什麼地方出了錯。您還可以爲查詢添加帶有標識符的鍵,以便知道哪個查詢出錯了。

爲了更好地處理,你可以寫這樣的UnitOfWork類:

class UnitOfWork 
{ 
    protected $_db; 
    protected $_errors; 
    protected $_queries; 
    public function __construct($db) { 
     $this->_db = $db; 
     $this->_errors = array(); 
     $this->_queries = array(); 
    } 
    public function addQuery($id, $sql) { 
     $this->_queries[$id] = $sql; 
     return $this; 
    } 
    public function getErrors() { 
     return $this->_errors; 
    }  
    public function try() { 
     $this->_db->autocommit($this->_db, FALSE); 
     foreach($this->_queries as $id => $query) { 
      if ($this->_db->query($query) === FALSE) { 
       $this->_errors[$id] = $this->_db->error; 
      } 
     } 
     $hasErrors = count($this->_errors); 
     ($hasErrors) ? $this->_db->rollback() : $this->_db->commit(); 
     $this->_db->autocommit($this->_db, TRUE); 
     return !$hasErrors; // return true on success 
    } 
} 

,你可以使用它像

$unit = new UnitOfWork($mysqli); 
$unit->addQuery('foo', 'SELECT foo FROM somewhere') 
    ->addQuery('bar', 'SELECT bar FROM somewhereElse') 
    ->addQuery('baz', 'SELECT baz WITH brokenQuery'); 

if($unit->try() === FALSE) { 
    print_r($unit->getErrors()); 
} 
3

mysqli::affected_rows將返回受上一操作MySQL的行數。

如果你正在做的事情是這樣的(僞代碼):

$db->query("insert ..."); 
$db->query("insert ..."); 
$db->query("insert ..."); 
$db->commit(); 
$num = $db->affected_rows(); 

你不會得到插入的行數:commit指令是最後執行的一個,它不會「影響「任何一行。


如果你想知道是否mysqli::commit succedeed與否,你應該檢查它的返回值(引用)

返回TRUE成功或FALSE上 失敗。

如果它返回true,那麼自從當前事務開始以來,所有先前的插入操作都將被提交。


如果發生錯誤,則可以使用mysqli::errno和/或mysqli::error來獲得關於它的信息。