我有一些代码可以创建一个用户,然后它会检查用户是否真实。本质上是这样的:
// INSERT statement fired in here
$user = self::_createUser( $params );
// Performs a sanity check by hitting DB with
// SELECT for the ID returned from creation within object
if ( !$user->isReal() ) {
throw new Exception( "User failed to create: " . var_export( $params, 1 ), MYCODE );
}
由于刚刚创建了用户,因此永远不应抛出此异常。这在生产或我的沙盒环境中永远不会发生。然而,我们的测试环境使用 Jenkins 一次启动多个测试,上面的代码行。
每次运行我们的套件时,都会在不同的测试中随机抛出异常。
我们打开了所有 MySQL 日志记录,发现在SELECT
之前调用了健全性,INSERT
但是SELECT
显然从数据库中选择了正确的 ID——除非创建工作,否则它不可能拥有。
MySQL服务器如何随机接收错误顺序的查询?以前从未见过这样的事情。
编辑这里有更多的代码澄清
function _createUser( $params ) {
// db returns connection using Zend, which translates to something like
// INSERT INTO users SET name='a'
// Returns ID of row inserted
$this->_id = self::db()->insert( 'users', $params );
}
function isReal() {
// Returns false when row is not there
return self::db()->fetchRow( "SELECT * FROM users WHERE id={$this->_id}" );
}
此外,MySQL 日志在所有情况下都按照我的预期显示查询,没有DEFER
编辑 2 使用命令行而不是 Jenkins 并行运行测试仍在使这种情况发生。同时它最多只能同时运行 7 个测试,并且代码中没有任何地方会在当时删除用户。除了在所有测试运行之前,没有一揽子删除。
编辑 3 好的,所以在运行的测试中,有一些持久连接。一种用于 MySQL,一种用于 Mongo。在我的套件运行之前,它通过从头开始重建数据库并擦除内存缓存来擦除 MySQL。它没有为 mongo 执行此操作,因此导致了一些其他随机错误。一旦我将 mongo 添加到重置脚本中,MySQL 错误似乎就消失了。这对我团队中的任何人或我自己来说都是零意义的。任何人都可以理解吗?