如何防止mysql隐式提交

如何防止mysql隐式提交

问题描述:

mysql documentation指出某些语句会在事务期间导致隐式提交。例如:如何防止mysql隐式提交

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble like foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 
ROLLBACK; 
SELECT * FROM foo; 

回滚之后,我得到一个排回从富 - 文档实际上说的ALTER TABLE不应该因为如果你使用临时关键字隐式提交,但ALTER TABLE TEMPORARY是无效的语法,并删除临时表不会导致暗示提交,所以我怀疑只有一个错误(至少5.5.29)

在任何情况下,我想要做的是告诉mysql永远不隐式提交,但是如果给出了会导致隐式提交的命令,则会失败/回滚。

我怀疑没有办法做到这一点,环顾四周,但我希望我错了。希望这里有人知道:)

,我刚刚成功地尝试了另一种哈克的方法是获得通过具体的MySQL命令创建表的DDL

SHOW CREATE TABLE `tableName` 

然后做一些正则表达式魔术和起草新DDL查询它将根据原始表创建一个临时表,将所有alter table更改合并到create table中。

在我的基于PHP的项目中,我做了以下操作来为临时表添加唯一索引。它做了诀窍,在事务中间不再发生隐式提交。这里

$createDDL = ... get from SHOW CREATE TABLE `tableName` 
$nr = 0; 
$createDDL = preg_replace("/CREATE TABLE `$tableName` \(/", "CREATE TEMPORARY TABLE `$tmpName` (\nUNIQUE `ukey-1` ($uniqCols),", $createDDL, -1, $nr); 
if (!$nr) 
    throw new Exception("CREATE TABLE replacement error. No reps made."); 
mysqli_query($con, $createDDL); 

编辑顺便说一些bug(功能)的报告(多年以来)。在第一个,你可以看到的状态下响应(约会至2006年):因为这种行为是一样的Oracle数据库中,这是一致的一个...

也许功能请求“垃圾邮件活动”应该启动此功能请求恢复!

+0

正确,这是一种解决方法,我最终做了类似的事情 - 真的希望有某种方式来做到这一点 - 但它似乎从错误报告他们不打算修复它。感谢您找到这些。 – 2013-05-30 19:59:29

至少在MySQL 5.5.19中,你是对的。文档声明ALTER TEMPORARY TABLE不会执行显式提交,但会对TEMPORARY关键字执行MySQL扼流。

我能想到的两种可能的解决方法:

解决方法1:

使用一个新的临时表中地方ALTER

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble LIKE foo; 
CREATE TEMPORARY TABLE mumble2 (bar INT UNSIGNED) SELECT * FROM mumble; 
ROLLBACK; 
SELECT * FROM foo; 

的最后一条语句产生以下输出:

Empty set (0.00 sec) 

不幸的是,没有办法将mumble2重命名为mumble,因为RENAME不允许用于临时表,并且ALTER mumble2 RENAME mumble隐式提交。

解决方法2:

不要使用临时表,而是产生一个子进程来运行,将导致隐式的命令提交:

方法1:

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 

过程2(并使用到MySQL的不同连接):

CREATE TABLE mumble LIKE foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 

过程1:

ROLLBACK; 
SELECT * FROM foo; 
DROP TABLE IF EXISTS mumble; 
+0

这个解决方法对于我的示例来说似乎很合理,但我真正想要的是解决此问题的更一般的解决方案。我不认为mysql应该在事务中隐式地提交 - 或者如果它要做的话,应该有某种方式(安全模式/例如)告诉它回滚和出错,而不是这样做。 – 2013-04-25 20:22:37

+0

我同意。文档建议在执行涉及'TEMPORARY'表的每个*每个DDL语句时,MySQL不应该暗示提交,因此可能已经在更新的版本中解决了这个问题。让我们交叉手指! – 2013-04-25 20:31:19

+0

不幸的是没有固定在5.6.11,我不确定是否打开了一个错误。我还没有找到一种方法来禁用隐式提交... – basos 2013-05-22 11:40:51