Php mysqli事务/保存点函数与手动使用query()的比较

Php mysqli事务/保存点函数与手动使用query()的比较,php,mysqli,transactions,mariadb,Php,Mysqli,Transactions,Mariadb,以下两段代码的工作方式是否相同,或者本机的mysqli事务函数是否做了一些额外的工作 我特别感兴趣的是在启动和提交事务/创建和发布保存点时如何处理和报告错误(如果有) 使用特定的mysqli函数进行事务处理: $db = new mysqli('localhost', 'root', 'batman', 'batcave'); if (!$db->begin_transaction()) { throw new Exception($db->error); } exc_query('

以下两段代码的工作方式是否相同,或者本机的
mysqli
事务函数是否做了一些额外的工作

我特别感兴趣的是在启动和提交事务/创建和发布保存点时如何处理和报告错误(如果有)

使用特定的
mysqli
函数进行事务处理:

$db = new mysqli('localhost', 'root', 'batman', 'batcave');
if (!$db->begin_transaction()) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
if (!$db->savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
if (!$db->release_savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="orange"');
if (!$db->commit()) { throw new Exception($db->error); }
$db = new mysqli('localhost', 'root', 'batman', 'batcave');
exc_query('START TRANSACTION');
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
exc_query('SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
exc_query('RELEASE SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="orange"');
exc_query('COMMIT');
function exc_query($q) {
    global $db;
    if (!$db->query($q)) {
        throw new Exception($db->error);
    }
}
使用普通的老
查询
函数做同样的事情:

$db = new mysqli('localhost', 'root', 'batman', 'batcave');
if (!$db->begin_transaction()) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
if (!$db->savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
if (!$db->release_savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="orange"');
if (!$db->commit()) { throw new Exception($db->error); }
$db = new mysqli('localhost', 'root', 'batman', 'batcave');
exc_query('START TRANSACTION');
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
exc_query('SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
exc_query('RELEASE SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="orange"');
exc_query('COMMIT');
function exc_query($q) {
    global $db;
    if (!$db->query($q)) {
        throw new Exception($db->error);
    }
}
执行上面使用的
exc\u查询
功能:

$db = new mysqli('localhost', 'root', 'batman', 'batcave');
if (!$db->begin_transaction()) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
if (!$db->savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
if (!$db->release_savepoint('vegetables')) { throw new Exception($db->error); }
exc_query('INSERT INTO utility_belt SET item="orange"');
if (!$db->commit()) { throw new Exception($db->error); }
$db = new mysqli('localhost', 'root', 'batman', 'batcave');
exc_query('START TRANSACTION');
exc_query('INSERT INTO utility_belt SET item="apple"');
exc_query('INSERT INTO utility_belt SET item="banana"');
exc_query('SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="potato"');
exc_query('DELETE FROM utility_belt WHERE item="turnip"');
exc_query('RELEASE SAVEPOINT vegetables');
exc_query('INSERT INTO utility_belt SET item="orange"');
exc_query('COMMIT');
function exc_query($q) {
    global $db;
    if (!$db->query($q)) {
        throw new Exception($db->error);
    }
}
我为什么要问这个问题?

在尝试执行
释放保存点
时,我偶尔会遇到问题,并且看到
保存点不存在
,即使我确定我以前已将
保存点
发送到服务器

根据我读到的内容,如果在我的示例中初始
启动事务失败,可能会抛出此错误。在这种情况下,事务将不会启动,因此
SAVEPOINT
将被静默忽略,但
RELEASE SAVEPOINT
随后将抛出错误

让我感到奇怪的是,在这些情况下,下面的一行没有捕捉到创建初始事务的任何失败:

if (!$db->query($q)) {
    throw new Exception($db->error);
}
。。。所以我不确定我是否正确。不幸的是,关于这些mysqli函数如何工作的官方PHP文档是基于:

PHP只向数据库发送完全相同的查询,而不发送其他任何查询


至于为什么
MySQLi::savepoint()
会与
MySQLi::query(“savepoint”)
有任何不同,我不知道。PHP源代码内部的错误处理似乎是相同的,因此如果出现问题,我希望您的
$db->query($q)
的结果是
false

您能澄清两个版本中的哪个版本会导致这些错误吗?我怀疑是后者(直接查询),但您的问题并不清楚。是的,第二个版本,仅使用
query()
,就是我们当前使用的版本。