我们在几个表上有一个简单的审计系统。这一切都很好,但每隔一段时间,我们就会在导致触发器触发的操作中得到这样的错误:
java.sql.SQLException: Explicit or implicit commit is not allowed in stored function or trigger.
不幸的是,我们无法弄清楚我们的触发器如何导致提交。
这些是(有时)导致错误的触发器:
CREATE
TRIGGER `my_schema`.`fileDescriptorInsertTrigger`
AFTER INSERT ON `my_schema`.`FILE_DESCRIPTOR`
FOR EACH ROW
insert into `AUDIT_EVENT`
(`applicationId`,`classifier`,`lastModified`)
values
(NEW.application,'FILE_AND_DIR',NOW())
on duplicate key
update lastModified=NOW();
CREATE
TRIGGER `my_schema`.`fileDescriptorUpdateTrigger`
AFTER UPDATE ON `my_schema`.`FILE_DESCRIPTOR`
FOR EACH ROW
update `AUDIT_EVENT`
set lastModified=NOW()
where classifier='FILE_AND_DIR'
and applicationId=NEW.application;
CREATE
TRIGGER `my_schema`.`fileDescriptorDeleteTrigger`
AFTER DELETE ON `my_schema`.`FILE_DESCRIPTOR`
FOR EACH ROW
update `AUDIT_EVENT`
set lastModified=NOW()
where classifier='FILE_AND_DIR'
and applicationId=OLD.application;
修改:根据要求输出show variables like '%commit%'
Variable_name Value
innodb_commit_concurrency 0
innodb_flush_log_at_trx_commit 1
修改2
错误只会在INSERT
my_schema.FILE_DESCRIPTOR
之后发生,因此会将其缩小到INSERT TRIGGER
,但即便如此,我也不知道它是如何导致提交的。
我们确实有Hibernate,所以它实际上是Hibernate正在进行插入,我们还有一个映射在AUDIT_EVENT
表上的实体,但是Hibernate(应该)永远不会写入{{1} } table。
如果有帮助,我上传了full stacktrace。
答案 0 :(得分:3)
这是因为 DEADLOCK ,这就是发生显式提交/回滚的原因。 请尝试处理此活动。 以下是一些可能对您有帮助的链接。
http://bugs.mysql.com/bug.php?id=24989
http://lists.mysql.com/commits/27471
尝试使用读取提交的隔离级别。
transaction-isolation = READ-COMMITTED
这可能会解决您的问题。这是参考链接
http://www.toofishes.net/blog/mysql-deadlocking-simple-inserts/
http://dev.mysql.com/doc/refman/5.5/en/innodb-deadlocks.html
希望这会有所帮助。