是否可以将一个sql事务跨多个函数合并为一个函数


Is it possible to do an sql transaction across multiple function into one?

我在另一个函数中使用了一些函数,这些函数可以更新某些内容,删除一些内容并插入,现在我的问题是,如果上面的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函数与数据库事务完全无关。这只是无关紧要的事。

数据库事务仅绑定到数据库连接。但是,只要所有函数都使用相同的连接,那么在事务中运行这三个函数就没有问题。

您应该为此使用数据库事务。

本质上,

  1. 你开始一笔交易
  2. 执行SQL查询
  3. 如果某个地方失败,则执行回滚,否则执行提交

但是也有一些棘手的问题,比如某些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,则可以执行所有命令。