Mysql Laravel悲观锁定无法阻止在多个重复请求中对未提交行进行选择

Mysql Laravel悲观锁定无法阻止在多个重复请求中对未提交行进行选择,mysql,laravel,locking,innodb,Mysql,Laravel,Locking,Innodb,双击按钮时,我试图防止无意的重复请求第二次更改我的型号。我做以下几件事 Log::debug('begintransaction'); DB::beginTransaction(); $pdo=DB::connection()->getPdo(); $pdo->exec('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE'); 试一试{ $user=\App\user::sharedLock()->find($id); Log::debug('Select

双击按钮时,我试图防止无意的重复请求第二次更改我的型号。我做以下几件事

Log::debug('begintransaction');
DB::beginTransaction();
$pdo=DB::connection()->getPdo();
$pdo->exec('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
试一试{
$user=\App\user::sharedLock()->find($id);
Log::debug('Select user:'。pickfield($user));
如果($user->checkout){
调试('已签出,回滚');
DB::rollback();
return Redirect::back()->带有('error','ready checked');
}
日志::调试(“更改签出…”);
$user->checkout=new\DateTime($request->input('checkout');
Log::debug('保存签出:'.pickfield($user));
$user->save();
日志::调试('Commit!');
DB::commit();
}捕获(\异常$e){
日志::调试('Error,rollback!');
DB::rollback();
}
事务仍然运行,因此彼此重叠,并使SELECT语句检索不一致的模型,即使在我使用可序列化隔离设置共享锁之后也是如此

[2019-05-17 01:02:45] local.DEBUG: Begin transaction
[2019-05-17 01:02:45] local.DEBUG: Begin transaction
[2019-05-17 01:02:45] local.DEBUG: Select user: {"id":3225,"checkout":null}
[2019-05-17 01:02:45] local.DEBUG: Changing checkout..
[2019-05-17 01:02:45] local.DEBUG: Saving checkout: {"id":3225,"checkout":{"date":"2019-05-17 01:02:45.428000","timezone_type":2,"timezone":"Z"}}
[2019-05-17 01:02:45] local.DEBUG: On model updating: {}
[2019-05-17 01:02:45] local.INFO: Sending email to user1@example.com
[2019-05-17 01:02:45] local.DEBUG: Begin transaction
[2019-05-17 01:02:45] local.DEBUG: Select user: {"id":3225,"checkout":null}
[2019-05-17 01:02:45] local.DEBUG: Changing checkout..
[2019-05-17 01:02:45] local.DEBUG: Saving checkout: {"id":3225,"checkout":{"date":"2019-05-17 01:02:45.604000","timezone_type":2,"timezone":"Z"}}
[2019-05-17 01:02:45] local.DEBUG: On model updating: {}
[2019-05-17 01:02:45] local.INFO: Sending email to user1@example.com
[2019-05-17 01:03:00] local.DEBUG: Commit!
[2019-05-17 01:03:00] local.DEBUG: Error, rollback!
< >我的代码已经保证在另一个事务的中间执行<代码> >选择< /代码>查询。我使用InnoDB

相关,无解决方案:


任何解释或解决方案?

一种可能的解决方案是在点击端点之前禁用按钮,这一点很重要,即使您设法解决了这个问题,但您不应该允许(尽可能多地)发送重复请求。

一个可能的解决方案是在点击端点之前禁用按钮,这一点很重要,即使您设法解决了这个问题,因为您根本不允许(尽可能多地)发送重复请求。

哦!我很困惑

是我的锁定类型不正确。它应该是
lockForUpdate

“for update”锁防止修改行或使用另一个共享锁选择行

共享锁时

共享锁可防止修改选定的行,直到 您的事务提交

我已经用MyISAM引擎进行了测试,但根本不起作用,这就是我感到困惑的原因。

哦!我很困惑

是我的锁定类型不正确。它应该是
lockForUpdate

“for update”锁防止修改行或使用另一个共享锁选择行

共享锁时

共享锁可防止修改选定的行,直到 您的事务提交


我已经用MyISAM引擎测试了这两个功能,但根本不起作用,这就是我感到困惑的原因。

谢谢,但是当你的按钮到处都是的时候会很麻烦。谢谢,但是当你的按钮到处都是的时候会很麻烦。MyISAM不支持事务,因此,您创建的任何锁都会在SELECT完成后立即释放。MyISAM不支持事务,因此您创建的任何锁都会在SELECT完成后立即释放。您是否使用“惰性”方法?或者是侵略性的?你能告诉我们生成的SQL吗?你使用的是“懒惰”方法吗?你能给我们看看生成的SQL吗?