gpt4 book ai didi

php - 多个浏览器连接获取相同的 DB 对象

转载 作者:太空宇宙 更新时间:2023-11-03 11:58:02 25 4
gpt4 key购买 nike

运行两个并发脚本,我想按顺序访问数据库,以便每个的自动增量主键是顺序的。即同时运行它们(实例 A 和实例 B)将导致

1-A, 2-A, 3-A, 1-B, 2-B, 3-B

但是,目前我得到
1-A, 1-B, 2-A, 2-B ,3-A ,3-B

在事务和锁定表没有像我预期的那样工作之后,我做了一些更深入的研究,看起来两个脚本(即使在不同的浏览器中运行)都获得了相同的连接。因此,由于它们都在同一 session 中,因此不会阻止另一个。我能做些什么来强制他们获得不同的连接(更改为 mysqli 或 PDO 不是一种选择,因为这是一个现有系统)?

Chrome 合金:
object(DB_mysql)#10 (26) {
["phptype"]=>
string(5) "mysql"
...

火狐
object(DB_mysql)#10 (26) {
["phptype"]=>
string(5) "mysql"
...

DB 创建是使用下面的 DSN 字符串完成的。 (里面还有一些其他的逻辑)
mysql://root:@127.0.0.1/XXX?new_link=true

查询运行:
LOCK TABLES xxxx write
SET autocommit=0
TRANSATION START
>>insert 1
>>insert 2
>>insert 3
COMMIT
UNLOCK TABLES

两个标签同时刷新:
表 1:
  [0]=>
int(56335766)
[1]=>
int(56335768)
[2]=>
int(56335770)

表 2:
array(3) {
[0]=>
int(56335765)
[1]=>
int(56335767)
[2]=>
int(56335769)
}

正如数据所示,尽管表被锁定,但数据是相互交织的。

最佳答案

问:为什么锁定不起作用?

答:根据问题的更新,显示SQL语句的顺序:

 LOCK TABLES xxx WRITE  
START TRANSACTION

问题是 START TRANSACTION正在释放锁。

此行为记录在 MySQL 引用手册中

引用: http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html

Rules for lock release

If a session begins a transaction (for example, with START TRANSACTION), an implicit UNLOCK TABLES is performed, which causes existing locks to be released. (For additional information about the interaction between table locking and transactions, see Section 13.3.5.1, “Interaction of Table Locking and Transactions”.



下面原始问题的原始答案

问:我可以做些什么来强制他们获得不同的连接?

答:我想你可能在那里吠错了树。很可能每个人都使用不同的数据库连接。

您显示的值 2-A , 2-B , 3-A 似乎是字符串值。

如果你做 SELECTORDER BY在这些字符串值上,行将按照您显示它们返回的顺序返回。没有 ORDER BY , MySQL 可以自由地以它想要的任何顺序返回行。如果 MySQL 使用索引返回行,而不执行排序操作,我们(几乎总是)观察到返回的行以与索引中出现的行相同的顺序返回。

如果您依赖于 AUTO_INCREMENT列的属性,不会将相同的值分配给两个不同的行(除非您使用的是 MyISAM 并且 AUTO_INCREMENT 列不是索引中的前导列...)

除此之外,两行不可能获得相同的 auto_increment 值。

或者,你在数据库表中得到的实际上更像是
  auto_id  byclient
------- --------
14156 A
14157 B
14158 A
14159 B
14160 A
14161 B
AUTO_INCREMENT属性在表上的列上,而不是“每个数据库连接”。插入行的两个(或更多)并发 session 可以执行“交错”值的操作。他们不必使用相同的数据库连接。

为了防止其他数据库连接同时对表执行 INSERT,您需要实现一种机制来实现这一点。在数据库层面,可以使用一些并发杀表锁。但是这些只保留到它们被释放,或者在数据库连接期间。如果您断开与数据库的连接,这些锁就会消失。

因此,如果两个单独的浏览器间歇性地调用同一个 PHP 页面,那对您没有帮助。即使您确实有办法为每个浏览器 session 获取单独的数据库连接。

我强烈怀疑您正在搅动数据库连接,为每次执行 PHP 脚本建立一个新的数据库连接。

(我认为您可能对使用相同的数据库连接大喊大叫。使用多个数据库连接您会得到相同的行为。)

跟进

我认为你问错了问题。为什么您需要“按顺序”设置 AUTO_INCREMENT id 值?如果这是实际要求,那么可能是 AUTO_INCREMENT不会是问题的合适解决方案。 (似乎您可能正在尝试让 AUTO_INCREMENT 执行它不适合的任务。在某些配置中,您不能保证 AUTO_INCREMENT 值将按照插入行的顺序递增。)

而不是要求 AUTO_INCREMENT 值是连续的(这真的是一个要求),我会备份,并考虑真正的要求是什么。也许识别插入每一行的“ session ”(让每个 session 在表中的一列中存储一个值,以及客户端为该 session 分配的升序整数值。然后你不必关心什么AUTO_INCREMENT 值被赋值:
 auto_id  session_id  seq_   
------- ---------- ----
75322 3e45bf4 1
75323 3e45bf4 2
75327 3e45bf4 3
75325 3e45bf4 4
75324 f51113e 1
75326 f51113e 2
75322 f51113e 3

关于php - 多个浏览器连接获取相同的 DB 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31174332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com