在開發(fā)過程中,不能保證每次數(shù)據(jù)庫操作都是成功的,有時候可能會出現(xiàn)錯誤,如果沒有使用事務(wù)處理機制,會導(dǎo)致開發(fā)中的數(shù)據(jù)完整性出現(xiàn)問題。而php作為一個開發(fā)網(wǎng)站比較常用的語言,也自然需要了解事務(wù)的處理方式。
一個實例來說明問題:假設(shè)需要對一個用戶的賬號進行扣款操作,同時將加款操作記錄到事務(wù)表中,必須保證扣款和記錄操作要么同時成功,要么同時失敗,不能出現(xiàn)只有一項成功的情況。其中,扣款需要使用delete語句,而記錄使用的是insert語句,因為insert語句的執(zhí)行只需要創(chuàng)建新的記錄,因此如果記錄表操作失敗,并不會對原有數(shù)據(jù)產(chǎn)生影響,而delete操作則不同。
//開始事務(wù) $pdo->beginTransaction();//開啟事務(wù) try { $deductionSql="delete FROM account WHERE id=? and balance>=?";//刪除操作 $user_id=1; $money=100; $stmt1 = $pdo->prepare($deductionSql); $stmt1->execute(array($user_id,$money)); if($stmt1->rowCount()==0){ throw new Exception('扣款失敗'); } $creationSql="insert into account_log(user_id,user_name,title,money) values(?,?,?,?)"; $user_name='nicole'; $title='賬戶扣款'; $stmt2 = $pdo->prepare($creationSql); $stmt2->execute(array($user_id,$user_name,$title,$money)); if($stmt2->rowCount()==0){ throw new Exception('記錄添加失敗'); } $pdo->commit(); //事務(wù)提交 } catch (Exception $e) { $pdo->rollback();//事務(wù)回滾 }
如上所示,使用try-catch語法,其中PDO的事務(wù)機制提供了beginTransaction,commit,rollback三個方法。
如果在try塊中代碼出現(xiàn)任何異常,則會自動跳轉(zhuǎn)到catch,執(zhí)行catch塊中的代碼,最后調(diào)用pdo的rollback方法,撤回當前的事務(wù)操作。如果沒有異常,代碼則會被正常執(zhí)行,再調(diào)用pdo的commit方法,提交當前的事務(wù),將扣款和記錄同時提交到數(shù)據(jù)庫中。
總結(jié)來看,當需要在一次操作中同時對多個表進行操作,并需要保證數(shù)據(jù)完整性時,就需要使用事務(wù),將所有操作放到一起,實現(xiàn)一次性提交,而不是逐個執(zhí)行每個操作,以此來確保數(shù)據(jù)的正確性。