【问题标题】:how to control concurrent operation of multiple users如何控制多个用户的并发操作
【发布时间】:2015-08-08 08:52:35
【问题描述】:

我会尽量让我的问题简洁明了,我正在为一家快递公司开发一个基于 php 的应用程序,其中多个用户可以登录到一个包含多个文本框字段和两个按钮的页面,第一个按钮(添加新)用于自动生成尚未插入数据库的新的空文档编号,第二个按钮(保存)用于将从文本框字段获取的数据与文档编号一起插入数据库,

现在,假设两个用户同时登录到该页面,并且他们都想向数据库中插入数据,假设 user1 按“添加新”按钮并获得一个文档编号,例如 1000 和同时 user2 也按下了“添加新”按钮,并获得了已经分配给 user1 的相同文档编号,因为 user1 尚未按下“保存”按钮,这意味着文档编号 1000 甚至不包含一行在数据库中,因为还没有用户按下“保存”按钮。

如果 user1 按下了“Save”按钮,将数据插入到文档编号为 1000 的数据库中,然后 user2 来并按下“Add New”,他将得到一个递增的值,即 1001,这对我来说很好。

我的问题是,如果两个用户同时按下“添加新”按钮,我如何分配不同的文档编号?

谁能帮我解决这个问题?是的,提前致谢:)

【问题讨论】:

  • 你在“添加”的时候创建了一个新的空文档记录,里面有一个数字,然后这个数字分配给第一个用户,不能分配给第二个用户,然后谁会得到当他们单击“添加”时下一个编号,您使用新编号为他们创建一个新的空文档记录
  • 同意立即分配 ID。如果用户点击“添加新”但从不保存它,您只会接受 ID 序列中的中断。即,您将有效地拥有大量“草稿”文档。
  • 不要将公共文档编号与私人内部 PK 混淆。你可以有某种时间限制,所以如果一个文档没有保存,它的文档编号会在很短的一段时间后被释放

标签: php mysql concurrency


【解决方案1】:
public static $is_locked = false;

function issue_document_number($params_if_required){
   //for core php write this line 
   global $is_locked; 
   $is_locked = true;
   //for OOP, if you are in class
   $this->is_locked = true;

   //make your calculations here to get desired number

   $is_locked = false;       
   return $document_number;
}

在调用时检查函数是否被锁定 sleep 1 或 2 秒,然后再次调用

while($is_locked==true){
   sleep(1);
}
$my_unique_number = issue_document_number($params_if_required);

进行查询并添加到数据库中

【讨论】:

  • 这究竟会实现什么,因为每个 PHP 请求都在自己的线程中运行并且与任何其他线程没有直接通信?每个线程都有自己的$is_locked,并且看不到任何其他线程的$is_locked
  • 只有提到的函数可以为所有请求发出id,但一次只能发出1个,所以其他请求会一直等待他,直到该函数空闲。
  • 不,它不会,因为该函数中没有任何东西会阻止它在另一个线程中为另一个请求运行......每个请求都会在它自己的线程中运行它自己的该函数的副本,完全相互独立。您似乎误解了 global 的含义.....global not 的意思是“跨所有线程”
  • 那么最好将$is_locked值保存在数据库或服务器的txt文件中
  • 您需要“锁定”可以从所有线程访问的东西,无论它是一个文件(如果您运行多个网络服务器,这可能会出现问题,除非您为此设置了一个可供所有服务器访问的共享驱动器文件),或数据库,甚至像 memcache 或 redis 这样的缓存存储
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 2020-10-12
  • 2020-12-22
  • 2011-11-13
  • 2016-02-23
  • 2016-12-29
  • 1970-01-01
相关资源
最近更新 更多