我在使用Laravel 4.2和DB::transaction时遇到了一个小问题。我遇到了一个事务不能回滚的问题,所以我尝试了最简单的代码片段,并将其放入routes.php中进行测试:
routes.php:
DB::transaction(function(){
$user = App::make("User");
$user->save();
throw new Exception("Should not create users");
});
...
...
...
Some other code here
简单地说,我尝试在事务闭包中创建用户,并在创建用户后抛出异常以强制回滚事务。我的问题是,即使抛出异常,事务也不会回滚。每次刷新应用程序时,我都会在数据库中获得新用户。相同的代码在本地机器上工作,但是在我计划用于生产的服务器上,它根本不回滚事务。你知道为什么吗?
编辑:
服务器MySql:5.1.73-cll - MySQL Community Server(GPLv2)
Server PHP:PHP 5.4.30(cli)(built:2014年7月19日15:22:18)
本地PHP:5.5.9
本地MySql:5.6.16
服务器位于CentOs上,而本地计算机是Windows 7。
4条答案
按热度按时间6ljaweal1#
所以我在回答我自己的问题。InnoDb不是默认的存储引擎,直到MySql 5.5。在我的情况下,MYISAM是默认的存储引擎,不支持事务。我必须做的是在我的MySQL的CPanel服务器安装中启用InnoDB。然后我必须确保我的Laravel迁移中的每个表都是使用InnoDB引擎创建的。我通过添加:
一旦所有的表都用InnoDB引擎设置好了,事务就可以按预期工作了。
m4pnthwp2#
另一种方法是使用
/config/database.php
将引擎的值从null更改为InnoDB
rm5edbpk3#
1.确保你已经在databases.php连接数组配置中设置了
'engine' => 'InnoDB'
。1.如果在项目中使用多个数据库连接,则需要指定要在哪个连接中提交和回滚。
vyswwuz24#
如果事务仍然没有为您回滚,并且您已经在使用
InnoDB
,则可能是由于您在内部运行的查询。例如,MySQL有一个bug/特性,其中
TRUNCATE <table>;
有一个隐式提交,所以在你尝试回滚之前,表就被保存了。解决方法是使用DELETE FROM <table>;
,然后是ALTER TABLE <table> AUTO_INCREMENT = 1;
(如果你希望保留重置auto_increment id的行为)。我建议在
php artisan tinker
中尝试一个基本的查询,如:请注意语句中的不一致性,在一个地方是
'users'
,在另一个地方是users
。请注意在原始语句中无法转义参数的危险,我必须将
$autoIncrement
类型转换为整数才能安全。如果有人知道解决方法,请告诉我们!我还包含了一些代码行,因为查询也可能由于外键约束而失败。
小心勘误表,还没有实现的用例,以及MySQL,PostgreSQL和其他引擎之间的不一致。
更多信息:
transaction doesn't work on truncate
https://laracasts.com/discuss/channels/eloquent/db-transaction-doesnt-appear-to-rollback-properly
Difference between Laravel's raw SQL functions
Can I use transactions with ALTER TABLE?