我有一些代码可以创建一个用户,然后在线下检查用户是否真实。基本上就是这样:
// 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。在我的套件运行之前,它是通过从头开始重建DB并擦除内存缓存来擦除MySQL。它不是为mongo做这个,因此导致一些其他随机错误。一旦我将mongo添加到重置脚本,似乎MySQL错误就消失了。这对我的团队或我自己的任何人都没有任何意义。任何人都可以理解这一点吗?
答案 0 :(得分:-1)
我不知道为什么,但两天后,这个错误就消失了。它像我的第三个编辑说的那样消失...在我确定当我清空MySQL和memcache之后,我也清空了mongo。我最好的猜测是,当糟糕的mongo数据导致异常时,PHP会以某种方式出现。不确定这是一个PHP错误还是我试图报告它听起来很疯狂。
虽然我发布了这个答案,但我仍然感谢任何额外的输入。