C# 存储过程中的MySQL事务不回滚
这是我的存储过程:C# 存储过程中的MySQL事务不回滚,c#,mysql,database,C#,Mysql,Database,这是我的存储过程: CREATE PROCEDURE `procedureName` ( IN var1 VARCHAR(45), IN var2 VARCHAR(100), IN var3 VARCHAR(45), IN var4 DATE, IN someMoreVars VARCHAR(100) ) COMMENT 'just a comment' BEGIN DECLARE tempVar INT DEFAULT -1; DECL
CREATE PROCEDURE `procedureName`
(
IN var1 VARCHAR(45),
IN var2 VARCHAR(100),
IN var3 VARCHAR(45),
IN var4 DATE,
IN someMoreVars VARCHAR(100)
)
COMMENT 'just a comment'
BEGIN
DECLARE tempVar INT DEFAULT -1;
DECLARE exit handler for sqlexception
BEGIN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'SQLError occured. Triggered ROLLBACK';
-- ERROR
ROLLBACK;
END;
DECLARE exit handler for sqlwarning
BEGIN
SIGNAL SQLSTATE '35000' SET MESSAGE_TEXT = 'SQLWarning occured. Triggered ROLLBACK';
-- WARNING
ROLLBACK;
END;
START TRANSACTION;
INSERT INTO `schemaName`.`table1` (`column1`, `column2`, `moreColumns`)
VALUES (var1, var2, moreVars);
SELECT LAST_INSERT_ID() INTO tempVar;
INSERT INTO `schemaName`.`table2` (`column1`, `column2`, `evenMoreColumns`)
VALUES (tempVar, var3, var4);
COMMIT;
END
为什么存储过程不回滚?当我使用的参数适用于第一次插入,但在第二次插入时引发异常时,此过程不会回滚,并且我在第一个表中得到数据,但在第二个表中没有数据
我正在使用InnoDB引擎
我已经用MySQL Workbench测试了这种行为,由于它在GUI中内置了这种奇怪的自动提交行为,我也通过从C#脚本调用过程来测试它
我还检查了文档中是否提到最后一个函数是导致隐式提交的函数。但是没有在列表中找到它。或者该函数是否调用另一个确实导致隐式提交的函数?如果有的话,有什么解决办法吗?
我需要调用此函数以将其主键用作第二个表中的外键。
如果这些信息有用的话:我也在使用触发器
这是其中一个表的insert触发器(它们几乎位于insert/update/delete上的所有表中):
谢谢:)为了让这篇文章保持最新信息: 几天前/几周前,我自己找到了一个解决方案来修复此错误 事实证明,问题在于必须在“信号”之前调用“回滚”。如果有人对此有详细的解释,请随意添加该信息。但在发出异常信号后根本不可能回滚。 因此,以下代码应该可以工作:
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'SQLError occured. Triggered ROLLBACK';
END;
当然,SQLWarning也是如此。看看我对SQLExecuteOptions的回答,谢谢,这确实很有趣。所以你认为这可能是当前MySQL服务器版本中的一个Bug?但我在第二次插入中导致异常的原因是,在配置为NOTNULL的列中将其中一个值设置为null。我想说,这并不是一个特殊的例外,但可能是最常见的例外之一。你真的认为即使是这个异常也没有得到正确的处理吗?很可能是触发器中的代码导致了提交,因为第一次
INSERT
上的触发器将在第二次INSERT
之前运行,因为我不是所有的错误都会触发SQLExection,这取决于错误发生的位置。所以得到正确的数字,然后像我在第二个代码中做的那样编程block@Nick哦,这对我来说很有意义。有什么办法可以防止这种情况发生吗?我将尝试在我的过程中明确地设置自动提交。但我想这不会有什么帮助,因为这不应该对交易产生影响。还有其他建议吗?
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'SQLError occured. Triggered ROLLBACK';
END;