I have a MySql query that uses a session user variable:
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;
The tables aren't particularly relevant, other than the fact that they both have an integer FileId field (auto-increment, primary key in table 1), and table1 has an integer data set id and a few DateTime timestamps.
This query gets run within a transaction, and gets run on a lot of different threads with different values for @dataSetId and @timestamp. I occasionally see that the result of the query has a data set ID and timestamp that do not match the provided parameters. What I get matches some other request that was retrieved earlier. This is fairly rare...most of the time I get exactly what I expect even with many threads.
I am aware that session variables can have previous state from a prior call, but I've only seen that be a problem when I set the variable within a SELECT, such as
SELECT @id := FileId FROM table1 WHERE ...
specifically when the WHERE causes nothing to match so @id doesn't get updated.
I've tested to make sure this isn't the problem here (ie, when the SELECT finds nothing, it sets @matchedId to null). And in fact the SELECT should be finding something. Running the same query in workbench gets me the right answer. Additionally I have added a SET @matchedId = 0; at the beginning of the query just to be extra sure, and it didn't change the behavior.
I've looked at the code several times and don't see any statics being used in the call stack that could cause problems.
So I'm guessing this is somehow the result of connection pooling and the connection that reproduced this problem was last used for the match I'm receiving, but I cannot figure out what mechanism could be responsible for the behavior. How can this query get a result that matches a previous request? Is there any way for me trace which pooled connections are being used for which requests? Any improvements I can make to the query?