如何防止MySQL会话中的隐式事务?

时间:2018-03-20 19:13:05

标签: mysql transactions

我正在使用MySQL数据库对大型应用程序进行测试。该语言可以轻松挂钩“提交”和“回滚”;那些使用SAVEPOINT技巧的人允许我的测试暂时改变数据库的状态,并在退出时将它们全部回滚。

但这是一个有很多贡献者的大项目,并且可能会有一个混合的DDL语句。隐式提交的任何语句都会破坏将数据库返回其原始状态的测试合同。有没有办法强制执行任何执行隐式提交命令的错误?

Cosiderations:

  1. read_only变量看起来很有前景,但限制性太强。我想允许插入/更新/删除语句。是否有类似但“更轻”的变量可以禁用DDL?
  2. MySQL是否有任何“挂钩”或“回调”机制来拦截呼叫,或者是会话中的所有呼叫,还是仅限某些命令?如果是这样,那么我可以写一个简单地在任何隐式提交命令上抛出异常的过程。
  3. 我确实有一些解决方法,我会在答案中提出。如果有人有更好或更简单的答案,那就接受了。

1 个答案:

答案 0 :(得分:2)

以下是两个解决方法,这些解决方法都不能完全满足我。

  1. REVOKE CREATE, ALTER, DROP, LOCK TABLES on MyDB.* FROM 'testuser'; - 当测试结束时,GRANT会在特权更改下进行。这个看起来很棒,但它需要一个DB用户使用GRANT& REVOKE privs。应用程序的数据库用户没有它们,这是正确的。理想情况下,运行这些测试的开发人员不需要执行任何额外的管理工作,例如获取额外的权限或创建新的数据库用户。

  2. 使用两阶段提交事务,而不是使用普通事务。这太棒了!它不需要任何特殊权限,它可以防止任何隐式提交,而无需列出甚至知道哪些语句导致这些提交,而且这是一个“自行消失”的变化。但是......它干扰了SAVEPOINTS,让我运行一些交易,回滚或中途提交,然后继续。这使得编写改变一些事物的测试变得困难。让检查测试并在测试后期使用这些更改。

  3.   

    mysql> XA START 0x123; - 查询正常,0行受影响(0.00秒)

         

    mysql>插入temp_yh_test值(0,'popbus'); - 查询正常,1行受影响(0.00秒)

         

    mysql>创建表temp_new_1(id int NOT NULL AUTO_INCREMENT,xyz   varchar(40),主键(id))ENGINE = InnoDB; - ERROR 1399(XAE07):XAER_RMFAIL:全局事务处于ACTIVE状态时无法执行命令