2016-12-03 52 views
0

我有一个Laravel 5.2后端和Angular 1前端应用程序。他们使用REST API进行通信。有一段代码可以在每次页面加载时更新一些数据库数据(应用程序是一种浏览器游戏,所以在这种情况下,玩家的资源和单位正在更新/生成),但我遇到了一些问题。Laravel可能的竞争状态?

在某些情况下,前端会同时请求多个API端点。如果自上次请求后生产出新单元,Entity应为attached()Player模型(多对多关系)。实际情况是,所有3个请求都试图附加新的Entity,最后在pivot表上以SQL error: duplicate key(不是确切的措词)附加。

该问题并非孤立于Eloquent,例如3个API请求同时导致生成3个报告消息等等。

解决此问题的最佳方法是什么?到目前为止,我试图用DB::transaction包装DB语句,但是这似乎没有解决问题(或者我做错了)。

谢谢任何​​有用的回复。

+0

您使用的和最新的数据库引擎是什么样的数据库?请记住,MySQL的MyISAM等传统数据库引擎不是事务性的,这意味着整个表在等待查询执行时被锁定。如果多个请求对于您的应用程序来说很常见,那么您可能不得不考虑使用像InnoDB这样的事务性数据库引擎。 – LePhleg

+0

1.什么是“所有3个请求”? 2.你如何发送它们:令人耳目一新的角度视图?快速刷新浏览器中的页面?从三个独立的前端实例发送它们? – bjauy

+0

@bjauy当用户在浏览器中刷新页面时,发生3个请求。应用程序的不同部分加载他们的数据非常多。 –

回答

0

根据L5.2 source codeattach似乎每次运行它时的记录插入到数据透视表。

其中一种解决方案可能是用syncWithoutDetaching([entity_id])代替attach

但是,在您的角度应用程序中限制单个请求的数量会更好。

+0

我认为'attach'错误只是Laravel一次执行所有三个连接的一个症状,这也是为什么3个报告消息会生成等等。 限制请求数量也不是一个解决方案,因为没有任何东西阻止用户打开多个选项卡并刷新页面。 –

0

在我结束了创建一直运行在后台Laravel命令结束:

while(true) { 
     updateUnitsExample(); 
     $this->info('Units updated for time '. date("H:m:s")); 
     sleep(1); 
} 
+0

或者你可以卸载更新到背景[队列](https://laravel.com/docs/5.2/queues)。 – bjauy

相关问题