简体   繁体   English

PHP和MySQL InnoDB:插入或更新后无法立即获得数据

[英]PHP & MySQL InnoDB: Data not available immediately after insert or update

I've just switched over from MyISAM tables to InnoDB as the row locking seems like it would be better than table locking. 我刚刚从MyISAM表切换到InnoDB,因为行锁定似乎比表锁定要好。

Problem is that now many of things I was doing before don't work. 问题在于,现在我之前所做的许多事情都无法正常工作。

For example, I have one script that recommends items to a user based on their browsing history. 例如,我有一个脚本可以根据用户的浏览历史向他们推荐项目。 This is done by inserting or updating rows into a recommendations table. 这是通过在建议表中插入或更新行来完成的。 The actual calculation of the recommendation is done though an SQL statement. 推荐的实际计算是通过SQL语句完成的。 So sometimes I am performing the recommendation statement, then immediately (in the same PHP script) requesting the results of this so it can be displayed to the user right there. 因此,有时我会执行推荐声明,然后立即(在相同的PHP脚本中)请求此结果,以便可以将其显示在此处。 With MyISAM this worked perfectly, but with InnoDB it sometimes will return the old results, or no results (if there didn't used to be any). 使用MyISAM可以完美地工作,但是使用InnoDB有时会返回旧结果,或者不返回任何结果(如果以前没有任何结果)。

Also I have a table that acts as a queue for something. 我还有一个表,可以作为某些东西的队列。 To use it I perform and update and then a select on the results of this update. 要使用它,我执行并更新,然后选择此更新的结果。 Again it works for MyISAM but not for InnoDB. 再次适用于MyISAM,但不适用于InnoDB。

How can I ensure that the rows are inserted or updated immediately in some cases? 在某些情况下,如何确保立即插入或更新行? In other cases I would be happy with a delayed insert or update if it speeds the query up. 在其他情况下,如果可以加快查询速度,我会对延迟的插入或更新感到满意。 But in the particular cases outlined about I need it to be immediate. 但是在概述的特定情况下,我需要立即采取行动。 Is there a PHP command to do this? 有PHP命令可以执行此操作吗? Or is it do with MySQL settings? 还是使用MySQL设置?

It sounds like you could be having transaction issues since moving to InnoDB http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html . 听起来自从移至InnoDB http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html以来,您可能遇到事务问题。

Unlike MyISAM, InnoDB supports database transactions that isolate your previous SQL commands until you have committed them with a special COMMIT sql command. 与MyISAM不同,InnoDB支持隔离以前的SQL命令的数据库事务,直到您使用特殊的COMMIT sql命令将它们提交为止。 Normally, this isn't a problem since you will be running off of the same transaction on the same database connection and AUTOCOMMIT is enabled by default. 通常,这不是问题,因为您将在同一数据库连接上运行同一事务,并且默认情况下启用AUTOCOMMIT The autocommit feature of MySQL will automatically commit the transaction after a data change, such as after an UPDATE . MySQL的自动提交功能将在数据更改后(例如在UPDATE之后)自动提交事务。 However, I would guess that you are connecting to the database multiple times (or perhaps using a library that is doing so) and your library or configuration is disabling autocommit. 但是,我想您会多次连接到数据库(或使用正在这样做的库),并且您的库或配置正在禁用自动提交。

You can test this easily by issuing the SQL COMMIT after your UPDATE and seeing if the problem disappears. 您可以通过在UPDATE之后发出SQL COMMIT并查看问题是否消失来轻松测试。 If this is the problem, the long-term solution depends on the libraries you are using, but generally you can enable autocommit again (either through your library or by removing the disabling entry from your my.cnf or my.ini file) or you can preferably start using transactions! 如果这是问题所在,则长期解决方案取决于您使用的库,但是通常您可以再次启用自动提交(通过您的库或通过从my.cnf或my.ini文件中删除禁用条目)或最好可以开始使用交易! There are plenty of articles everywhere for "MySQL data transactions tutorial." 到处都有很多关于“ MySQL数据交易教程”的文章。

You can enable autocommit via PHP by executing the SQL SET AUTOCOMMIT=1; 您可以通过执行SQL SET AUTOCOMMIT=1;来通过PHP启用自动提交SET AUTOCOMMIT=1; once before executing the rest of your SQL. 在执行其余SQL之前一次。

This all assumes you are not having replication issues. 所有这些都假定您没有复制问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM