我在另一个函数中使用了一些函数,这些函数可以更新某些内容,删除一些内容并插入,现在我的问题是,如果上面的2个成功,或者1个不成功,可能会导致灾难性的结果。那么,是否可以将1个事务用于所有3个函数。。。例如:
public static function do_stuff()
{
//run sql in function
SELF::function_sql_one_insert();
SELF::function_sql_two_update();
SELF::function_sql_three_delete();
}
像这样:
public static function test()
{
SELF::function_sql_one_insert();
SELF::function_sql_two_update();
SELF::function_sql_three_delete();
}
public static function function_sql_one_insert()
{
//sql to run
$sql = "INSERT INTO table
(
fake_row_one,
fake_row_two
)
VALUES
(
?,
?
)";
//run sql
$fake_insert = $database->prepare($sql);
$fake_insert->execute("yeah", "okay");
}
public static function function_sql_two_update()
{
//sql to run
$sql = "UPDATE table
SET fake_row_one = ?
WHERE fake_row_two = ?";
//run sql
$fake_update = $database->prepare($sql);
$fake_update->execute("blahblah", "okay");
}
public static function function_sql_three_delete()
{
//sql to run
$sql = "DELETE FROM TABLE
WHERE fake_row_two = ?";
//run sql
$fake_delete = $database->prepare($sql);
$fake_delete->execute("okay");
}
我想说的是,如果一个失败了,就把所有的东西都恢复回来。这可能吗?如果不是,我该怎么办?如果是,这有什么缺点吗?
Php函数与数据库事务完全无关。这只是无关紧要的事。
数据库事务仅绑定到数据库连接。但是,只要所有函数都使用相同的连接,那么在事务中运行这三个函数就没有问题。
您应该为此使用数据库事务。
本质上,
- 你开始一笔交易
- 执行SQL查询
- 如果某个地方失败,则执行回滚,否则执行提交
但是也有一些棘手的问题,比如某些sql语句会自行提交,所以请阅读您正在使用的数据库的所有官方文档。
更多信息:http://php.net/manual/en/pdo.begintransaction.php
但请记住,并非所有数据库都支持事务。例如MySQL中的MyISAM表不支持事务。
您可能想将这些表转换为InnoDB,请参阅此处,例如:如何将MyISAM中的所有表转换为InnoDB?
我使用这种方式:
class Teste {
public $mysqli;
public $erro = array();
public function __construct(){
$this->mysqli = new 'mysqli(DB_HOST,DB_USERNAME,DB_PASSWORD,DATABASE);
$this->mysqli->set_charset("utf8");
}
public function start_trans(){
$this->mysqli->autocommit(false);
}
public function end_trans(){
if(count($this->erro) == 0){
$this->mysqli->commit();
echo "success";
} else {
$this->mysqli->rollback();
echo "error";
}
}
public function example1(){
$stmt = $this->mysqli->query("insert into veiculos (placa, modelo) values (1,1)");
if(!$stmt){
$this->erro[] = "Erro #143309082017 <code>" . $this->mysqli->error . "</code>";
}
return (count($this->erro) < 1)? true : false;
}
public function example2(){
$stmt = $this->mysqli->query("insert into veiculos (placa, modelo) values (2,2)");
if(!$stmt){
$this->erro[] = "Erro #143309082017 <code>" . $this->mysqli->error . "</code>";
}
return (count($this->erro) < 1)? true : false;
}
public function example3(){
$this->mysqli->autocommit(false);
$stmt = $this->mysqli->query("insert into veiculos (placa, modelo) values (3,3)");
if(!$stmt){
$this->erro[] = "Erro #143309082017 <code>" . $this->mysqli->error . "</code>";
}
return (count($this->erro) < 1)? true : false;
}
}
$action = new Teste;
$action->start_trans();
$action->example1();
$action->example2();
$action->example3();
$action->end_trans();
也许你可以试试这样的东西:
$working = true;
try
{
SELF::function_sql_one_insert();
} catch (Exception $e)
{
if($e != "")
$working = false;
}
对所有函数都尝试此操作。如果$working为true,则可以执行所有命令。