我之前写过一个数据库类,我在大多数项目中使用它,最近扩展了类以处理事务。
下面的Transaction类似乎无法正常工作,服务器是MySQL innoDB,我已经检查过我的数据库上的事务(使用PHPMyAdmin)。所以这显然是我的代码中的错误或我的误解。
<?php
/**
* Description of Database
*
* @author http://stackoverflow.com/users/820750/gerve
*/
class Database {
private $connection;
public function __construct($dbServer, $dbName, $dbUser, $dbPassword) {
$this->connection = mysql_connect($dbServer, $dbUser, $dbPassword);
mysql_select_db($dbName, $this->connection);
}
public function query($query, $die = true) {
return new Query($query, $this->connection, $die);
}
public function escape($param) {
return mysql_real_escape_string($param, $this->connection);
}
public function transaction() {
return new Transaction($this->connection);
}
}
class Query {
private $query;
public $count;
public $countModified;
public $queryString;
public function __construct($query, $link_identifier, $die = true) {
if($die){
$this->query = mysql_query($query, $link_identifier) or die(mysql_error());
}
else{
$this->query = mysql_query($query, $link_identifier);
}
$this->count = is_resource($this->query) ? mysql_num_rows($this->query) : 0;
$this->countModified = mysql_affected_rows($link_identifier);
$this->queryString = $query;
}
public function nextRow() {
return mysql_fetch_object($this->query);
}
public function allRows() {
$array = array();
while($row = mysql_fetch_object($this->query)){
$array[] = $row;
}
return $row;
}
}
class Transaction {
private $connection;
private $isAlive;
public function __construct($link_identifier) {
$this->connection = $link_identifier;
$this->query("BEGIN");
$this->isAlive = true;
}
public function query($query) {
if($this->isAlive){
$q = new Query($query, $this->connection, false);
if(mysql_error()){
$this->rollBack();
return false;
}
else{
return $q;
}
}
}
public function rollBack() {
if($this->isAlive){
$this->query("ROLLBACK");
$this->isAlive = false;
}
}
public function commit() {
if($this->isAlive){
$this->query("COMMIT");
$this->isAlive = false;
return true;
}
else{
return false;
}
}
}
?>
编辑 - 类的使用示例
$DB = new Database(dbServer, dbName, dbUser, dbPassword);
$transaction = $DB->transaction();
$transaction->query("INSERT INTO myTable `c1`, `c2` VALUES('1', '2')"); //Works
$transaction->query("INSERT INTO jhsdjkag 5dafa 545"); //Fails
$transaction->query("INSERT INTO myTable2 `c1`, `c2` VALUES('3', '4')"); //Works
$transaction->commit();
上面的代码不应该在数据库中插入任何行,第二个查询失败,所以没有任何行应该成功。
我的问题是它不会回滚,无论查询失败,都会插入行。
答案 0 :(得分:0)
尝试使用START TRANSACTION
代替BEGIN
START TRANSACTION
允许您使用WITH CONSISTENT SNAPSHOT
:
WITH CONSISTENT SNAPSHOT选项为能够使用它的存储引擎启动consistent read。这仅适用于InnoDB。
答案 1 :(得分:0)
我发现代码中存在错误,只是在__construct()
中。这很简单,我只改了1行:
发件人:强>
public function __construct($link_identifier) {
$this->connection = $link_identifier;
$this->query("BEGIN");
$this->isAlive = true;
}
以强>
public function __construct($link_identifier) {
$this->connection = $link_identifier;
$this->isAlive = true;
$this->query("BEGIN");
}
- &gt;在第一个“BEGIN”查询后设置isAlive,这意味着从未发送过BEGIN。