我的测试在开始测试之前使用特征RefreshDatabase
来“迁移新鲜”,并为每种测试方法使用事务。
迁移工作正常,但交易根本不起作用。
我尝试公开我的设置:
RefreshDatabase
$connectionsToTransact
一起进行测试,并使用默认连接进行测试。交易不起作用我的setUp方法:
protected function setUp()
{
parent::setUp();
Queue::fake();
}
您可以在此Gist中找到完整的Test Class和Test基类: https://gist.github.com/patriziotomato/e25de1e160dace08edefa682b64bd150
我已经尝试调试了,并且也开始使用PDO启动和回滚事务,所以看起来laravel代码尝试进行事务处理和回滚,但它在我的测试中没有任何影响。
我需要一些其他可能出错的想法
答案 0 :(得分:2)
您可能正在使用Model::truncate()
。
不幸的是,自MySQL 5.1.32起,truncate()
与事务“不兼容”。您可以删除表,但不能在事务内truncate()
。
http://dev.mysql.com/doc/refman/5.1/en/truncate-table.html
根据此URL,从MySQL 5.1.32开始,TRUNCATE TABLE为DDL, 不像DELETE这样的DML。这意味着TRUNCATE TABLE将导致 事务块中间的隐式COMMIT。因此,使用DELETE 在表上的FROM,您需要清空而不是TRUNCATE TABLE。
StackOverflow和Laracasts的相关答案:
答案 1 :(得分:1)
要回滚在您的测试文件中进行的交易,您可以使用DatabaseTransactions
:
...
use Illuminate\Foundation\Testing\DatabaseTransactions;
...
class SomeTest extends TestCase {
use DatabaseTransactions;
public some_assertion_method()
{
...
}
答案 2 :(得分:1)
我有同样的问题。从来没有找到确切的原因,但有一个解决方法 - 手动启动和回滚事务:
public function setUp()
{
parent::setUp();
DB::beginTransaction();
}
public function tearDown()
{
DB::rollback();
parent::tearDown();
}
答案 3 :(得分:0)
我自己有一个类似的MySQL设置问题。我还从上面尝试了Anthony的解决方案,并且也看到了相同的...1305 SAVEPOINT trans2 does not exist...
错误。
在我的案例中,罪魁祸首是代码中的Model::truncate()
操作(用于重新导入命令)。某种程度上,这似乎使Laravel的事务/回滚处理(或MySQL的?)感到不安,从而导致上述错误。使用Model::all()->each->delete()
可以解决我的问题。 (经过一些进一步的测试,看来我也无法重置auto_increment值,所以这是问题所在。)
值得注意的是,它可能不会在内存数据库中发生,而在MySQL设置中发生,例如,如果流氓条目保持完整,很容易与即将到来的测试混在一起,从而导致难以调试的错误,所以请小心...:)
更新 最佳答案on this Laracast thread实际上说明事务操作在操作期间具有隐式提交,并在测试期间引发事务堆栈。
答案 4 :(得分:-2)
更改文件phpunit.xml
<php>
<env name="DB_CONNECTION" value="mysq"/>
<env name="APP_ENV" value="local"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="SMS_DRIVER" value="array"/>
</php>
将此特征添加到测试文件中:
use DatabaseTransactions;