在从数据库进行读写时,如何防止并发?

时间:2018-07-20 19:21:09

标签: php mysql concurrency innodb backend

我也有一个表,其中包含用户登录信息和注册。因此,当两个用户连续尝试添加其详细信息时:

  1. 写入冲突和表都不会更新吗?

  2. 使用线程进行这些写操作不是一个好主意。对于每次写入,都会创建一个新线程,这将阻塞服务器。服务器负责由它自己管理吗?

  3. 锁定表是个好主意吗?

我的后端在PHP / Apache和MySQL(InnoDB)上运行数据库。

3 个答案:

答案 0 :(得分:2)

关系数据库旨在避免这种情况。除非您是从头开始设计自己的关系数据库,否则您不必担心它们。

简而言之,只要知道这一点:每当启动写操作时,都会有一个行级锁。如果另一个事务要写入同一行,则必须等到第一个事务释放锁。这是关系数据库的基础部分。您不需要添加锁,因为他们已经想到了:)

您可以阅读有关MySQL如何执行锁定以避免死锁和其他事务错误here的更多信息。

答案 1 :(得分:0)

如果您对此实在有点偏执,或者当您注册用户并需要原子操作时您正在做多件事,那么您可能希望研究在MySQL中使用事务。 http://www.mysqltutorial.org/mysql-transaction.aspx

上有关于交易的不错的文章

答案 2 :(得分:0)

BEGIN;
do related reads/writes to the data
COMMIT;

在该“事务”中,该连接可以看到一致的数据视图,并阻止其他任何人弄乱该视图。

有例外。主要是

BEGIN
SELECT ... FOR UPDATE;
fiddle with the values SELECTed
UPDATE ...;  -- and change those values
COMMIT;

SELECT .. FOR UPDATE宣布不应篡改的内容。如果另一个连接要弄乱相同的行,则必须等到您的COMMIT为止,此时他可能会发现情况已发生变化,因此他需要做一些不同的事情。但是,总的来说,这避免了“僵局”,在僵局中,两笔交易彼此之间步履蹒跚,以至于必须“回滚”一笔交易。

使用这样的技术,只能短暂且相对准确地防止“并发”。也就是说,如果两个连接正在处理不同行,则两者都可以继续进行-无需“防止并发”。