我创建了一个 PDO 类来帮助我与 MySQL 服务器连接和通信。 我正在尝试向类中添加一个函数或方法,以帮助我打开 MySQL 事务以及提交和回滚。我从来没有使用过提交和回滚。
我认为,场景会以某种方式在每次调用此类时停止自动提交,并在引发错误时回滚,并在每次此类 id 关闭时提交。
我的两个问题是: 1)打开连接然后运行多个查询提交(如果没有错误)是一个好主意,否则回滚然后关闭连接? 2)如何调用我设法将其添加到我现有的类(class)中? 这是我当前的 PHP 类(class)
<?php
class connection {
private $connString;
private $userName;
private $passCode;
private $server;
private $pdo;
private $errorMessage;
private $pdo_opt = array();
protected $lastQueryTime;
protected $lastQuery;
protected $effectedRows;
function __construct($dbName = DATABASE_NAME, $serverName = DATABASE_HOST){
//SET PDO options
if(TESTING_ENVIRONMENT == 1){
$this->pdo_opt[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$this->pdo_opt[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_ASSOC;
}
$this->pdo_opt[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8';
$this->pdo_opt[PDO::SQLSRV_ATTR_ENCODING] = PDO::SQLSRV_ENCODING_UTF8;
//sets credentials
$this->setConnectionCredentials($dbName, $serverName);
//start the connect
$this->startConnection();
}
function startConnection(){
$this->pdo = new PDO($this->connString, $this->userName, $this->passCode, $this->pdo_opt);
if( ! $this->pdo){
$this->errorMessage = 'Failed to connect to database. Please try to refresh this page in 1 minute. ';
$this->errorMessage .= 'However, if you continue to see this message please contact your system administrator.';
echo $this->getError();
}
}
//this will close the PDO connection
public function endConnection(){
$this->pdo = null;
}
//return a dataset with the results
public function getDataSet($query, $data = NULL)
{
$start = microtime(true);
$cmd = $this->pdo->prepare( $query );
$cmd->execute($data);
$this->effectedRows = $cmd->rowCount();
$ret = $cmd->fetchAll();
//$cmd->closeCursor();
$this->lastQueryTime = microtime(true) - $start;
$this->lastQuery = $query;
return $ret;
}
public function processQuery($query, $data = NULL)
{
$start = microtime(true);
//$this->pdo->beginTransaction();
$cmd = $this->pdo->prepare( $query );
$ret = $cmd->execute($data);
//$this->pdo->commit();
//$cmd->closeCursor();
$this->effectedRows = $cmd->rowCount();
$this->lastQueryTime = microtime(true) - $start;
$this->lastQuery = $query;
return $ret;
}
//return last insert id
public function lastInsertId($name = NULL) {
if(!$this->pdo) {
return false;
}
return $this->pdo->lastInsertId($name);
}
//return last insert id
public function rowCount() {
return $this->effectedRows;
}
public function getOneResult($query, $data = NULL){
$cmd = $this->pdo->prepare( $query );
$cmd->execute($data);
return $cmd->fetchColumn();
}
public function getError(){
if($this->errorMessage != '')
return $this->errorMessage;
else
return true; //no errors found
}
//this where you need to set new server credentials with a new case statment
function setConnectionCredentials($dbName, $serv){
switch($serv){
//the defaults are predefined in the APP_configuration file - DO NOT CHANGE THE DEFAULT
default:
$this->connString = 'mysql:host='.DATABASE_HOST.';dbname='.DATABASE_NAME.';charset=utf8';
$this->userName = DATABASE_USERNAME;
$this->passCode = DATABASE_PASSWORD;
break;
}
}
public function lastQueryTime() {
if(!$this->lastQueryTime) {
throw new Exception('no query has been executed yet');
}
return $this->lastQueryTime;
}
public function lastQuery() {
if(!$this->lastQuery) {
throw new Exception('no query has been executed yet');
}
return $this->lastQuery;
}
}
?>
已编辑 收集通知后我需要这样吗?
$db = new connection();
$db->beginTransaction(); //begin transaction
$db->processQuery(); //process query #1
$db->processQuery(); //process query #2
$db->commit(); //commit changes
$db->endConnection(); //close connection
public function beginTransaction(){
$this->pdo->beginTransaction();
}
public function commit(){
$this->pdo->commit();
}
public function rollBack(){
$this->pdo->rollBack();
}
//this will close the PDO connection
public function endConnection(){
$this->pdo = null;
}
最佳答案
/* Begin a transaction, turning off autocommit */
$dbh->beginTransaction();
/* Commit the changes */
$dbh->commit();
此时,感觉您的 connection
类的级别相当低。我的猜测是它没有足够的信息来自行了解何时开始事务以及何时提交事务。您可能必须提供相应的方法(以及 rollback
方法),并让您的类的用户在需要时调用它们。
关于你的问题,事务不仅仅是回滚本地更改。也是关于atomicity 。这是一系列操作,要么全部完成,要么根本不完成。不要忘记将对您的数据库进行并发访问。有时,您不希望有人在您操作数据时更改数据。
关于php - 如何在 PDO 类中添加 MySQL 事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18004715/