iT邦幫忙

0

請問在PHP的PDO若使用了beginTransaction後,是否無法再使用prepare+bindParam

$db->beginTransaction();

$sqls = array("replace into test1 values(:a,:b)",
	 		  "replace into test2 values(:c,:d)");
	 		  
$params = array(array(":a"=>"test1a",":b"=>"test1b"),array(":c"=>"test2c",":d"=>"test2d"));

reset($sqls);
reset($params);

foreach ($sqls as $sql){
    unset($st);
    $st=$db->prepare($sql);
	
	$param=current($params);
	next($params);
	
	foreach ($param as $key => $value){
    	$st->bindParam($key, $param[$key]);
	}
	
	$st->execute();
}

$db->rollBack();

我在最後執行了rollBack,但資料還是一樣寫入了。上網查了許多PDO's Transaction 範例,都是不透過statment直接使用PDO::prepare + PDO::commit

$db->beginTransaction();

$st = $db->exec("insert into test1('a','b')");
$st = $db->exec("insert into test1('c','d')");

$db->rollBack();

但剛好我這兒必需使用bindParam做參數的綁定,但試了很多種作法都不能成功,請問是否我有那兒沒有考慮到呢?

2 個回答

2
wiseguy
iT邦超人 1 級 ‧ 2011-09-13 09:41:14
最佳解答

beginTransaction() 不能在 prepare() 之前。
因為你在迴圈中有兩次 prepare(),所以每 prepare() 一次就要用一次 Transaction。

0
godstamp
iT邦新手 3 級 ‧ 2011-09-14 23:04:24

以前大量使用過,並沒有這種限制...
使用 Transaction 主要應該是看你的資料表型態是否支援,如果你是使用 MySQL,預設的資料表型態通常是用 MyISAM,MyISAM 不支援 transaction,所以建議改成 InnoDB 試試,另外在 $db->beginTransaction(); 與 db->commit(); 之間執行的 SQL 語句中,如果有任何一句提到的資料表不支援 transaction,那麼 $db->beginTransaction(); 也會失去效用。
你的程式碼看起來怪怪的,是測試用的嗎?

通常我都是類似這樣使用,給你參考參考...

<pre class="c" name="code">
try{
	
	$db->beginTransaction();
	
	//訪問資料庫的一些動作,處理結果有問題就丟出例外
	$res = ..... 
	if(!$res) throw new Exception(....);
	
	$db->commit();
	
}catch (Exception $e){
	
	$db->rollBack();
	
	echo $e->getMessage();
}

我要發表回答

立即登入回答