【问题标题】:how to know when mysql INSERT is finished (multiple connections)如何知道 mysql INSERT 何时完成(多个连接)
【发布时间】:2011-07-11 04:06:31
【问题描述】:

我有这样的多数据库连接情况:

db connection 1: INSERT xyz
(very short time passes)
db connection 2: SELECT [looking for xyz]

有时SELECT 找到xyz,有时却没有(因为它与INSERT 位于不同的数据库连接上)。如果我在INSERT then the SELECT 后面加上sleep(1) 总是会找到xyz

对于数据库连接 1,我怎样才能让它等到 INSERT 完成并且新行可用于在另一个数据库连接上运行的 SELECTs

我的桌子是innodb。用例是在连接 1 上插入经过身份验证的会话 ID,然后重定向到经过身份验证的页面,然后当对经过身份验证的页面的请求进入(在另一个连接上)时,我们会查找会话 ID 来验证请求。如果我们稍微放慢登录速度并让它等到INSERT 完全完成就可以了,这样在返回之前,经过身份验证的会话 ID 可用于其他请求。

【问题讨论】:

  • 你可以检查最后一个插入的id
  • 您使用什么编码语言?哪个司机?
  • is connection2 连接到同一个数据库服务器或从/副本数据库。
  • @shakti:最后一个插入 ID 是基于每个连接的。连接 2 不会看到连接 1 的最后插入是什么。
  • 我正在使用 php。 connection2 在同一个数据库上。每个连接都在为进入我的站点的不同 http 请求提供服务。第一个是登录,第二个是对经过身份验证的页面的请求。谢谢,伙计们!

标签: mysql select insert


【解决方案1】:

第一个问题,为什么同一个用户有两个不同的连接?

如果你真的想保持两个会话,你可以玩table locking

连接1,发送这些sql语句:

LOCK TABLE mytable WRITE; -- mytable is know locked, nobody else can access it
INSERT xyz; -- insert data in database
UNLOCK TABLES; -- unlock the table, the rows ARE inserted

连接 2:

SELECT [looking for xyz]

如果连接 2 尝试在连接 1 解锁表之前访问数据库,则连接将不得不等待。当表被解锁时,行会被插入,所以 select 会返回想要的结果。

【讨论】:

  • 连接是由对我网站的 http 请求创建的。在登录期间,我这样做:(1)​​验证用户名/密码,(2)如果有效,生成会话 ID 并插入到用户会话表中并将其保存在 cookie 中,(3)然后执行 301 重定向到用户的起始页(经过身份验证的页面)。当下一个 http 请求进来时,我看到它是一个需要身份验证的页面。我抓取 cookie 以获取会话 ID 索引,然后执行 SELECT 来查找它。此 SELECT 位于不同的数据库连接上,因为它是一个新的 http 请求。
  • 那么你是说如果我锁定故事,然后插入,然后解锁表,那么当解锁返回来自插入的数据时,将被刷新,以便稍后SELECT在另一个连接上就能找到吗?
  • 我的意思是,由于所有语句都是按顺序执行的,因此在 INSERT 完成之前不会执行 UNLOCK 并且当 LOCK 处于活动状态时,第二个连接将无法访问数据库。
  • 哦。好吧,这是我的情况:连接 1:INSERT,然后重定向到新的 url(301 重定向)。连接 2(第二个 http 请求,来自重定向的 url):SELECT,查找 INSERT 写入的会话 ID。我需要在 INSERT 之后暂停某种形式,以便有时间刷新该数据,以便当该线程创建下一个请求(301 重定向)时,下一个请求可以访问插入的数据。如果可以保证在解锁完成时将刷新插入的数据,我可以在 INSERT 周围锁定/解锁。或者我应该看看 FLUSH 命令?
  • 谢谢,Krtek。我添加了锁定/解锁,但仍然看到问题。插入的行是否可能在某个队列中,等待刷新?如果我在插入 (sleep(2)) 后强制延迟 2 秒,那么它工作正常。顺序是: Thread1: INSERT xyz, sleep(2), redirect to new url;然后线程 2:接收新 url 的请求,选择 [查找 xyz],找到 xyz 并继续。但是,如果我取出 sleep(2),那么即使 INSERT 周围有 LOCK/UNLOCK,它也找不到 xzy。感谢您的帮助!
【解决方案2】:

因为插入语句是一个事务;一旦您的插入语句完成,它就在数据库中;我假设这两个与数据库的连接是使用两个不同的线程建立的;并且您同时发出两个命令(此时还没有插入 xyz。

鉴于您描述的用例,我不确定这是否应该通过两个不同的数据库连接。然而;首先应该被证明是错误的;您可能想使用锁定文件或其他东西来指示“事务”真正完成。

【讨论】:

    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2013-02-01
    • 2011-04-05
    相关资源
    最近更新 更多