1

我有一个表(InnoDB),它经常被插入、更新和读取(通常相隔几毫秒)。我注意到有时在 INSERT/UPDATE 之后的 SELECT 语句会得到陈旧的数据。我认为这是由于缓存造成的,但是放在SQL_NO_CACHE它前面之后并没有真正做任何事情。

你如何确保 SELECT 总是等到前一个 INSERT/UPDATE 完成并且不从缓存中获取数据?请注意,这些语句是从单独的请求中执行的(不在同一代码执行中)。

也许我误解了 SQL_NO_CACHE 实际上做了什么......

更新

@Uday,INSERT、SELECT 和 UPDATE 语句如下所示:

INSERT myTable (id, startTime) VALUES(1234, 123456)

UPDATE myTable SET startTime = 123456 WHERE id = 1234

SELECT SQL_NO_CACHE * FROM myTable ORDER BY startTime

我尝试使用没有运气的交易。

更多更新

我认为这实际上是 INSERT 的问题,而不是 UPDATE 的问题。SELECT 语句总是尝试获取按时间排序的最新行。但由于 INSERT 不执行任何表级锁定,因此 SELECT 可能会获取旧数据。执行 INSERT 时有没有办法强制表级锁定?

4

2 回答 2

1

查询缓存不是问题。写入使缓存无效。

MySQL 优先考虑写入,并且使用默认隔离级别 (REPEATABLE READ),您的 SELECT 将不得不等待 UPDATE 完成。

如果您为 MyISAM 启用了CONCURRENT INSERTS ,则可以对 INSERT 进行不同的处理,InnoDB 也使用记录锁定,因此它不必等待表末尾的插入。

那么这可能是一种竞争条件吗?您确定您的 SELECT 发生在 UPDATE 之后吗?您是否正在从可能尚未传播更新的复制服务器中读取?

如果问题出在并发 INSERT 上,您需要在 MyISAM 上禁用 CONCURRENT INSERT,或者在 INSERT 期间使用 LOCK TABLES 显式锁定表。InnoDB 的解决方案是相同的,使用 LOCK TABLES 显式锁定 INSERT 上的表。

于 2012-05-10T15:44:09.107 回答
0

A)
如果您根本不需要缓存(对于任何 SELECT),请完全禁用查询缓存。

B)
如果你只想要一个会话,你可以像“set session query_cache_type = 0;”那样做 这将为该特定会话设置此设置。

在任何一种情况下都额外使用 SQL_NO_CAHCE。

于 2012-05-10T15:27:15.760 回答