phpBB sql 交易功能不工作
phpBB sql transaction function not working
我正在使用 phpBB,但这段代码没有按预期工作。它只是使用 phpBB sql_transaction
函数来启动一个 sql 事务,然后提交它。但是应该在中途抛出异常并使用相同的函数发出回滚。
但是,回滚从未发生。查询 1 和 2 生效,我无法让它们回滚。
documentation 声明如果有 sql 错误,它会自动发出回滚,但如果有 php 错误,我正在尝试回滚,比如超时什么的。
我正在使用 MySQL 5.7、phpBB 3.0.11 和 php 5.6。
有人可以指出问题吗?
$db->sql_transaction('begin');
try {
$sql = 'UPDATE aaa_temp SET method = "a" WHERE id = 1';
$db->sql_query($sql);
$sql = 'UPDATE aaa_temp SET method = "b" WHERE id = 2';
$db->sql_query($sql);
throw new Exception('OMG TOTAL ERROR');
$sql = 'UPDATE aaa_temp SET method = "c" WHERE id = 3';
$db->sql_query($sql);
} catch (Exception $ex) {
$db->sql_transaction('rollback');
trigger_error($ex->getMessage(), E_USER_ERROR);
}
$db->sql_transaction('commit');
提前致谢!我知道这一定是非常简单和愚蠢的事情,但如果需要更多细节,请告诉我。
编辑:很明显,我说的是 MySQL 中的 SQL 交易。
您对异常的工作原理有误解。如果你有一个 try{...}catch(...){...}
块,并且在 try{...}
部分内的某处抛出异常,那么这是一个信号,表明你的代码流将跳转到 catch(...){...}
块的开头。
抛出异常之前发生的所有代码都会发生。只有 try
块内的代码不会发生异常之后的代码。没有 rollback
消除之前完成的所有流程,因为这对 php 开发人员来说极其(异常)困难。想象一下,如果您的 php 代码执行发送电子邮件之类的操作。当电子邮件已经发送时,您如何期望回滚发生?因此,不会发生回滚。
原来 table 我试图回滚更新到使用的是 MyISAM 存储引擎,它不支持事务。
具有讽刺意味的是,这正是 phpBB 构建它们的方式。 sql_transaction('rollback')
返回 true,因为回滚确实有效,只是没有收到关于数据未回滚的 SQL 警告。
通过启用 MySQL 中的 general_query_log
来解决这个问题,以准确查看此功能在后台执行的操作:
SET AUTOCOMMIT=0;
UPDATE aaa_temp SET method = "a" WHERE id = 1;
UPDATE aaa_temp SET method = "b" WHERE id = 2;
ROLLBACK;
SET AUTOCOMMIT=1;
因此,由于我混合使用了 MyISAM 和 InnoDB table,对后者的更改被回滚,而对前者的更改则没有。
我正在使用 phpBB,但这段代码没有按预期工作。它只是使用 phpBB sql_transaction
函数来启动一个 sql 事务,然后提交它。但是应该在中途抛出异常并使用相同的函数发出回滚。
但是,回滚从未发生。查询 1 和 2 生效,我无法让它们回滚。
documentation 声明如果有 sql 错误,它会自动发出回滚,但如果有 php 错误,我正在尝试回滚,比如超时什么的。
我正在使用 MySQL 5.7、phpBB 3.0.11 和 php 5.6。
有人可以指出问题吗?
$db->sql_transaction('begin');
try {
$sql = 'UPDATE aaa_temp SET method = "a" WHERE id = 1';
$db->sql_query($sql);
$sql = 'UPDATE aaa_temp SET method = "b" WHERE id = 2';
$db->sql_query($sql);
throw new Exception('OMG TOTAL ERROR');
$sql = 'UPDATE aaa_temp SET method = "c" WHERE id = 3';
$db->sql_query($sql);
} catch (Exception $ex) {
$db->sql_transaction('rollback');
trigger_error($ex->getMessage(), E_USER_ERROR);
}
$db->sql_transaction('commit');
提前致谢!我知道这一定是非常简单和愚蠢的事情,但如果需要更多细节,请告诉我。
编辑:很明显,我说的是 MySQL 中的 SQL 交易。
您对异常的工作原理有误解。如果你有一个 try{...}catch(...){...}
块,并且在 try{...}
部分内的某处抛出异常,那么这是一个信号,表明你的代码流将跳转到 catch(...){...}
块的开头。
抛出异常之前发生的所有代码都会发生。只有 try
块内的代码不会发生异常之后的代码。没有 rollback
消除之前完成的所有流程,因为这对 php 开发人员来说极其(异常)困难。想象一下,如果您的 php 代码执行发送电子邮件之类的操作。当电子邮件已经发送时,您如何期望回滚发生?因此,不会发生回滚。
原来 table 我试图回滚更新到使用的是 MyISAM 存储引擎,它不支持事务。
具有讽刺意味的是,这正是 phpBB 构建它们的方式。 sql_transaction('rollback')
返回 true,因为回滚确实有效,只是没有收到关于数据未回滚的 SQL 警告。
通过启用 MySQL 中的 general_query_log
来解决这个问题,以准确查看此功能在后台执行的操作:
SET AUTOCOMMIT=0;
UPDATE aaa_temp SET method = "a" WHERE id = 1;
UPDATE aaa_temp SET method = "b" WHERE id = 2;
ROLLBACK;
SET AUTOCOMMIT=1;
因此,由于我混合使用了 MyISAM 和 InnoDB table,对后者的更改被回滚,而对前者的更改则没有。