New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pysqlite] Duplicate rows can be returned after rolling back a transaction #77557
Comments
DescriptionRolling back a transaction causes all statements associated with that transaction to be reset, which allows the statements to be used again from the pysqlite statement cache. This can interact with various methods on This appears to be very similar to bpo-10513 and bpo-23129. # Impact Repro steps
Possible solutions
# Example
|
Sorry, wrong bug. |
Erlend, please take a look at this bug. |
I believe the former proposed solution is the correct solution. I'm digging though the pysqlite git history (both in the original repo and in CPython), the SQLite changelogs, and different test suites to prove me wrong :) I'm using bpo-44092 to track my findings. |
Since 243b6c3 (21-08-19), this bug can't be reproduced. In sqlite3_stmt *stmt = NULL;
while ((stmt = sqlite3_next_stmt(self->db, stmt))) {
if (sqlite3_stmt_busy(stmt)) {
(void)sqlite3_reset(stmt);
}
}
But the `pysqlite_Statement.in_use` flag is not reset.
In `_pysqlite_query_execute()` function, if `pysqlite_Statement.in_use` flag is 1, it creates a new `pysqlite_Statement` instance. So this line will use a new statement: gen = conn.execute("SELECT c FROM t WHERE ?", (1,)) The duplicate row is from A digressive suggestion is whether it can be changed like this, and add a check for resetting statement. So that statements are not allowed to be reset by other Cursors, which may improve code robust: typedef struct
{
...
- int in_use;
+ pysqlite_Cursor *in_use; // points to the attached cursor
...
} pysqlite_Statement; |
This issue is not resolved, but was covered by a problematic behavior. |
Yes, this will be resolved in bpo-44092. Hopefully I'll be able to land it sooner than later. |
#70214 / bpo-44092 has removed the old workaround where pending statements were reset before a rollback. Since version 3.7.11, SQLite no longer has any issues with pending statements and rollbacks, so we remove the workaround, since we require SQLite 3.7.15 or newer in CPython. As a side effect, pysqlite_do_all_statements() has now been removed, as it is unused code. Following #70214, this issue is no longer an issue; I close it as fixed. Ma Lin: if you have problems with the LRU cache, please open a new issue. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: