5

我们在几个表上有一个简单的审计系统。这一切都很好,但是每隔一段时间,我们就会在导致触发器触发的操作上收到这样的错误:

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该错误只会在on之后发生my_schema.FILE_DESCRIPTOR,因此会将其范围缩小到,INSERT TRIGGER但即便如此我也不知道它如何导致提交。

我们在此之上确实有 Hibernate,所以实际上是 Hibernate 执行插入操作,并且我们还有一个实体映射到AUDIT_EVENT表上,但 Hibernate(应该)永远不会写入AUDIT_EVENT表。

如果有帮助,我上传了完整的堆栈跟踪。

4

1 回答 1

3

发生这种情况是因为死锁,这就是显式提交/回滚发生的原因。请尝试处理此活动。以下是一些可能对您有所帮助的链接。

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

希望这会有所帮助。

于 2013-02-25T19:07:01.460 回答