2015-09-11 108 views
2

假设我有一个函数用于在某些情况下将数据库中名为project_id的列加1。 (由于在确定是否增加之前必须运行逻辑,因此假定自动增量不会满足此用例。同步PHP数据库查询

当用户单击“新建项目”,该功能在数据库中查找当前最大的PROJECT_ID,做一些其他的东西,并通过1

递增PROJECT_ID添加行有没有一种可能,当多个用户连接时,服务器处理某个其他消息所需的时间会导致多个用户获取相同的project_id?如果是这样,你会如何去避免这个问题?以这种方式增加是一个坏主意吗?

下面是一个例子。这个例子是基于Laravel的,但这个问题一般适用。

function ReallyLongFunction() { 
    //figure out what the current max project_id is and increment by 1 
    $newProjectId = Project::max("project_id")+1; 


    //Some other stuff that the server has to do. I am exaggerating here the length of time. 
    //If another user triggers this function, will both users will have the same project id? 
    sleep(2); 

    //Insert new row into database 
    $project = new TempProject; 
    $project->project_id = $newProjectId; 
    $project->save(); 
} 
+0

我不是数据库专家,但我会说,是的,这是不好的做法。如果您试图在代码中正确执行自动增量,为什么不自动递增工作? – samrap

+0

每次用户按下“新建项目”按钮时,您可以在数据库中创建一个“草稿”记录,并在取消时刻录新的自动增量ID。 – Scuzzy

回答

2

在你自己的代码中做一个好主意sql server在内部可以做得更好。 $newProjectId = Project::max("project_id")+1;听起来非常像auto_increment的替代品。但是,如果你的要求是比这更复杂,你需要locks

[LOW_PRIORITY]写锁:

持有锁可以读取和写入表中的会话。

只有拥有该锁的会话才能访问该表。其他 会话可以访问它,直到锁定被释放。

在保持WRITE 锁的同时锁定其他会话对该表的请求。

LOW_PRIORITY修饰符影响锁定调度,如果WRITE锁 请求必须等待(稍后介绍)。

如果因任何表上的其他 会话持有的锁而必须等待LOCK TABLES语句,则会阻塞,直到所有锁都可以获得 。

如果很多用户同时访问同一页面,则响应将开始减慢,因为第二个请求无法提供,直到第一个请求完成为止。

+1

感谢您的快速回复......您已确认我的怀疑,这并非是最好的办法。 – Andrew