我有一个表(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时强制表级锁定?
答案 0 :(得分:1)
查询缓存不是问题。写入使缓存无效。
MySQL优先考虑写入并使用默认隔离级别(REPEATABLE READ),您的SELECT必须等待UPDATE完成。
如果为MyISAM启用CONCURRENT INSERTS,则可以区别对待INSERT,InnoDB也使用记录锁定,因此不必等待表末尾的插入。
这可能是一场竞争条件吗?你确定你的SELECT在UPDATE之后发生了吗?您是否从可能尚未传播更新的复制服务器进行读取?
如果问题在于并发INSERT,则需要在MyISAM上禁用CONCURRENT INSERT,或者在INSERT期间使用LOCK TABLES显式锁定表。对于InnoDB,解决方案是相同的,使用LOCK TABLES显式锁定INSERT上的表。
答案 1 :(得分:0)
A)
如果您根本不需要缓存(对于任何SELECT),请禁用查询
完全缓存。
B)
如果你想只在一个会话中使用它,你可以这样做
“set session query_cache_type = 0;”这将为此设置
特别会议。
在任何一种情况下都使用SQL_NO_CAHCE。