多个mysqli准备了带有事务的语句


Multiple mysqli prepared statements with transactions

我正试图弄清楚如何将sql事务与mysqli准备的语句一起使用。我找不到任何使用多个准备好的语句(不是OO)的示例,所以我真的不知道如何使用它们的事务。这是我能想到的最接近的:

    mysqli_autocommit($database, FALSE);
    $transferq = 'INSERT INTO money (user_id, bank, onhand, type, amount, source) VALUES (?, ?, ?, ?, ?, ?)';
    $transferstmt = mysqli_stmt_init($database);
    mysqli_stmt_prepare($transferstmt, $transferq);
    mysqli_stmt_bind_param($transferstmt, 'iiisis', $userid, $newbank, $newmoney, $type, $amount, $source);
    mysqli_stmt_execute($transferstmt);
    $insertq = 'UPDATE users SET money=?, bank=? WHERE user_id=' . $userid . ' LIMIT 1';
    $insertstmt = mysqli_stmt_init($database);
    mysqli_stmt_prepare($insertstmt, $insertq);
    mysqli_stmt_bind_param($insertstmt, 'ii', $newmoney, $newbank);
    mysqli_stmt_execute($insertstmt);
    mysqli_commit($database);

但是,我不知道这是否可行。不过,我最大的问题是,我不确定如何检查查询是否失败(因此也不确定是否提交)。我看到一个例子,我认为它做了类似的事情

if(mysqli_stmt_execute($stmt)){
    mysqli_commit($database);
}else{
    mysqli_rollback($database);
}

但我真的不能这么做,因为我有多个准备好的语句要执行。

这是怎么回事?

也许我不理解你的问题,但这个呢?

mysqli_autocommit($database, FALSE);
$transferq = 'INSERT INTO money (user_id, bank, onhand, type, amount, source) VALUES (?, ?, ?, ?, ?, ?)';
$transferstmt = mysqli_stmt_init($database);
mysqli_stmt_prepare($transferstmt, $transferq);
mysqli_stmt_bind_param($transferstmt, 'iiisis', $userid, $newbank, $newmoney, $type, $amount, $source);
if (not mysqli_stmt_execute($transferstmt) ){
    mysqli_rollback($database);
    return;
}
$insertq = 'UPDATE users SET money=?, bank=? WHERE user_id=' . $userid . ' LIMIT 1';
$insertstmt = mysqli_stmt_init($database);
mysqli_stmt_prepare($insertstmt, $insertq);
mysqli_stmt_bind_param($insertstmt, 'ii', $newmoney, $newbank);
if (not mysqli_stmt_execute($insertstmt) ){
    mysqli_rollback($database);
    return;
}
mysqli_commit($database);

如果使用mysqli或PDO的这种面向对象的形式(没有事务,作为数据库工作方式的示例)的下一个级别:

class my_database{
    private static $inner_link_to_driver;
    protected static function factory( ){
        if (not static::$inner_link_to_driver){
            static::$inner_link_to_driver = new ...(USER, SERVER, PASSWD, PORT);
        }
        return static::$inner_link_to_driver;
    }
    public static function do_something($params, &$message ){
        $query = "...";
        $stmt = static::factory()->prepare($query);
        if (not $stmp ){
            $message = 'Error prepare query '.$query.PHP_EOL.static::factory()-> ..(get_error);
            return FALSE;
        }
        if (not $stmt->execute($params) ){
            $message = 'Error execute query '.$query.PHP_EOL.static::factory()-> ..(get_error);
            return FALSE;
        }
        return TRUE;
    }
}