MySQL 数据库事务是不是会使用 RefreshDatabase 或 DatabaseTransactions 破坏 Laravel PHPUnit 测试?

Posted

技术标签:

【中文标题】MySQL 数据库事务是不是会使用 RefreshDatabase 或 DatabaseTransactions 破坏 Laravel PHPUnit 测试?【英文标题】:Do MySQL database transactions break Laravel PHPUnit tests using RefreshDatabase or DatabaseTransactions?MySQL 数据库事务是否会使用 RefreshDatabase 或 DatabaseTransactions 破坏 Laravel PHPUnit 测试? 【发布时间】:2019-11-17 12:23:54 【问题描述】:

我正在为一个项目编写一些 phpUnit 功能测试,这是姗姗来迟。其中之一命中了许多修改数据库的路由 - 直到现在,我一直在其中一些路由中使用数据库事务。

如果我在测试中使用 RefreshDatabaseDatabaseTransactions 特征,它会失败并出现一个奇怪的错误:

Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\ClassM]

如果我删除特征(因此数据将保持不变),则测试通过。

我检查并从相关路由中删除了我的所有数据库事务,现在测试确实通过RefreshDatabase

我怀疑问题在于 mysql 不支持嵌套事务,并且这两个特征都使用事务。但这意味着,如果我想使用 RefreshDatabase 运行测试(迄今为止最好的选择!),我根本无法在我的代码中使用事务。

正确吗?这似乎是一个主要限制。

【问题讨论】:

【参考方案1】:

我找到了一种解决方法 - 这似乎有点奇怪。我主要使用“手动”交易方法 - 例如

DB::beginTransaction();
try 
    $user = User::create([...]); etc.
    DB::commit();

catch (...) 
    DB::rollBack();

我只是切换到了闭包方式:

DB::transaction(function () 
    $user = User::create([...]); etc.
);

不知道为什么会修复它!

【讨论】:

以上是关于MySQL 数据库事务是不是会使用 RefreshDatabase 或 DatabaseTransactions 破坏 Laravel PHPUnit 测试?的主要内容,如果未能解决你的问题,请参考以下文章

MySql关于缺省值时事务的处理(转)

mysql -- 事务隔离级别以及java中事务提交的步骤

「Spring」事务失效的场景

Spring事务失效的 8 大原因

mysql如何快速备份

Mysql数据库分布式事务XA详解