如果正在进行交易,如何避免阻止选择?

时间:2016-05-30 11:27:21

标签: php mysql transactions

我有一些InnoDB表和一个启动事务的脚本。在此事务中,一个表的不同行会更新,其他行将插入另一个表中,并执行许多选择。这必须可靠地发生,因此我使用REPEATABLE READ作为隔离级别的默认事务。此交易可能需要一些时间。

现在,当其他脚本(网页请求)同时执行时,他们会在数据库中进行一些选择。不幸的是,那些选择等到事务结束,因为他们从相同的表中读取。所选数据可以是事务的更新数据,但也可以是其他数据。

这种阻止是我想要避免的。我想立即向用户显示网页,不能等待交易(一两秒钟是可以接受的,但交易有时会更长)。

那我怎么做选择呢?我猜数据可能并不总是准确的。但这比让用户等待20秒更好。

我应该

  • 使用'FOR UPDATE'或'LOCK IN SHARE MODE'与交易中的选择?
  • 使用另一个隔离级别?
  • 将阅读选择也放在交易中吗?
  • 做些不同的事情?

我认为这是一个非常常见的要求,但我找不到简单的答案。

注意:接下来的事情是保护并发写入事务。但是现在我只想确保在事务期间至少并行读取不被阻止。

1 个答案:

答案 0 :(得分:0)

好的,这不是一个真正的答案,但我想我应该告诉我发现了什么:

我想,它与MySQL的行为没有任何关系。它实际上是挂起PHP请求。也就是说,当第一个PHP调用启动了长时间正在进行的事务时,对其他页面的进一步PHP调用已被挂起。他们被绞死的原因是第一次请求锁定了会话session_start()不再起作用了。就在第一个请求完成(或超时)时,进一步的请求将再次起作用。

由于使用长事务的PHP调用不需要在会话中写入任何内容,因此我只需在此调用中使用session_write_close()关闭会话。现在,进一步的请求不再挂起。

This是我的暗示。

结论:数据库选择未被阻止。