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

时间:2015-07-02 01:34:29

标签: php mysql

运行我想要按顺序访问数据库的两个并发脚本,以便每个自动增量主键是顺序的。即,当时运行它们(实例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

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

铬:

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

火狐

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

使用下面的DSN字符串完成数据库创建。 (那里有一些其他的逻辑)

mysql://root:@127.0.0.1/XXX?new_link=true

查询RUN:

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)
}

正如数据显示的那样,尽管表格被锁定,数据仍然交织在一起。

1 个答案:

答案 0 :(得分:3)

问:为什么锁定没有工作?

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

 LOCK TABLES xxx WRITE  
 START TRANSACTION

问题是START TRANSACTION正在释放锁定。

MySQL Reference Manua中记录了这种行为

参考:http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html

  

锁定释放规则

如果会话开始一个事务(例如,使用START TRANSACTION),则隐式{执行{1}}会导致释放现有锁。 (有关表锁定和事务之间交互的其他信息,请参阅Section 13.3.5.1, “Interaction of Table Locking and Transactions”

原始问题的原始答案

问:我有什么办法可以强迫他们获得不同的联系吗?

A:我想你可能会在那里咆哮错误的树。很可能每个人都使用不同的数据库连接。

您显示的值 UNLOCK TABLES 2-A 2-B 似乎是字符串值

如果对这些字符串值执行3-A SELECT,则会按照显示返回的顺序返回行。如果没有ORDER BY,则MySQL是免费的以任何顺序返回行。如果MySQL使用索引返回行,而不执行排序操作,我们(几乎总是)观察到行返回的行与索引中出现的行的顺序相同。

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

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

或者,您在数据库表中获得的内容实际上更像是

AUTO_INCREMENT

auto_id byclient ------- -------- 14156 A 14157 B 14158 A 14159 B 14160 A 14161 B 属性位于表的列上,而不是"每个数据库连接"。插入行的两个(或更多)并发会话可以执行"交错"价值。他们不必使用相同的数据库连接。

为了防止其他数据库连接同时对表执行INSERT,您需要实现一种机制来实现这一点。在数据库级别,您可以使用一些并发查杀表锁。但这些只会在它们被释放之前或数据库连接期间一直持有。如果您从数据库断开连接,那些锁就会消失。

因此,如果两个独立的浏览器间歇性地调用相同的PHP页面,那将无法帮助您。即使你确实有办法为每个浏览器会话获得单独的数据库连接。

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

(我认为你可能在使用相同的数据库连接时出错了。你会在多个数据库连接中获得相同的行为。)

<强>后续

我认为你问的是错误的问题。为什么你需要具有AUTO_INCREMENT id值&#34;按顺序&#34;?如果这是一个实际要求,则可能AUTO_INCREMENT不适合解决问题。 (好像你可能试图让AUTO_INCREMENT执行一个不适合的任务。在某些配置中,你不能保证AUTO_INCREMENT值会按插入行的顺序升序。)

我不是要求AUTO_INCREMENT值是连续的(这确实是一个要求),而是要备份,而不是考虑真正的要求是什么。也许确定&#34;会话&#34;插入每一行(让每个会话在表中的列中存储一个值,以及客户端为该会话分配的升序整数值。然后你不必关心分配了什么AUTO_INCREMENT值:

AUTO_INCREMENT