我有一个使用会话用户变量的MySql查询:
SET @matchedId = (
SELECT FileId FROM table1
WHERE DataSetId = @dataSetId
AND TimestampUtc = @timestamp
AND ConvertedTimeUtc IS NULL ORDER BY ReferenceTimeUtc DESC LIMIT 1
);
SELECT * FROM table1 WHERE FileId = @matchedId;
SELECT * FROM table2 WHERE FileId = @matchedId;
这些表并不特别相关,除了它们都有一个整数FileId字段(自动增量,表1中的主键),而table1有一个整数数据集id和几个DateTime时间戳。 / p>
此查询在事务中运行,并在具有@dataSetId和@timestamp的不同值的许多不同线程上运行。我偶尔会看到查询结果的数据集ID和时间戳与提供的参数不匹配。我得到的内容与先前检索到的其他请求相匹配。这是相当罕见的......大多数时候,即使有很多线程,我也能得到我所期望的。
我知道会话变量可以具有先前调用的先前状态,但是当我在SELECT中设置变量时,我只看到这是一个问题,例如
SELECT @id := FileId FROM table1 WHERE ...
特别是当WHERE导致无法匹配时,@ if不会更新。
我已经测试过以确保这不是问题(例如,当SELECT没有找到任何内容时,它会将@matchedId设置为null)。事实上,SELECT应该找到一些东西。在工作台中运行相同的查询得到了正确的答案。另外我添加了一个SET @matchedId = 0;在查询的开头只是为了更加确定,并没有改变行为。
我已多次查看代码,并且看不到任何可能导致问题的调用堆栈中使用的静态。
所以我猜这是以某种方式连接池的结果,并且重现此问题的连接最后用于我正在接收的匹配,但我无法弄清楚哪种机制可能导致该行为。该查询如何获得与先前请求匹配的结果?有没有办法让我跟踪哪些池连接被用于哪些请求?我可以对查询做出哪些改进?