fix(wren): connect MSSqlConnector with autocommit so statements are not left in an open transaction - #2705
Conversation
…ot left in an open transaction pyodbc defaults to autocommit=False, and mssql.py never called .commit() or set .autocommit, so every statement on the process-cached connection ran inside one transaction that was never closed. Mirrors canner.py, mysql.py, and redshift.py, which already turn autocommit on. Fixes Canner#2704.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. WalkthroughThe MSSQL connector now enables autocommit when it creates its cached ChangesMSSQL autocommit
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: 🔵 Low · up to This change prevents long-lived uncommitted MSSQL transactions and makes successful statements durable immediately. It is mergeable with owner awareness that multi-statement write workflows may no longer be atomic if a later statement fails. Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
MSSqlConnectoropens itspyodbcconnection withoutautocommit=True, so every statement runs inside one implicit transaction that is never committed for the connection's whole process life. This connectsautocommit=Truein_connect_mssql_pyodbc, matching the shape already used bycanner.py,mysql.py, andredshift.py.What failure does this repair?
pyodbc defaults to
autocommit=False._connect_mssql_pyodbccallspyodbc.connect(";".join(connection_parts))with noautocommitargument, and nothing inmssql.pycalls.commit(),.rollback(), or sets.autocommitafterward. SinceWrenEngine._get_connector()caches this connector for the engine's lifetime, the connection stays in one open transaction for as long as the process runs, which blocks SQL Server's transaction log truncation for the whole time (log_reuse_wait_desc = 'ACTIVE_TRANSACTION') and leaves any write statement issued through the connector uncommitted.Fixes #2704.
How is it tested?
test_mssql_connects_with_autocommitintests/unit/test_mssql_connection.py, which patcheswren.connector.mssql.pyodbc(same fixture the file's other tests already use) and assertspyodbc.connectis called withautocommit=True. Runs in CI'stest-unitjob (pytest tests/unit/).python:3.11-slim, dependencies fromuv sync --locked(which resolves the publishedwren-core-py==0.7.5wheel, no local Rust build needed since this change does not touchwren-core-py): 1 failed / 18 passed on unmodifiedmain(56e007d), 19 passed on this branch.tests/unit/(excludingtest_memory.py/test_mcp_server.py, matchingwren-ci.yml'stest-unitjob exactly): 1240 passed, 2 skipped, on the branch.ruff format --check src/andruff check src/(thelintjob's exact commands): clean.tests/connectors/test_mssql.py, the live-SQL-Server integration suite. It needstestcontainers[mssql]and a real SQL Server container, andwren-ci.yml'stest-connectormatrix only coverspostgres/mysql, so this file does not execute in CI either. I read it to confirm the fault (its own setup connections already doconn.autocommit = True, working around the exact gap this PR closes) but did not attempt to stand up a container for it.Duplicate check
competing-prs.shagainstcore/wren/src/wren/connector/mssql.py, run at scout time and again immediately before this push (70/70 open PRs swept both times): 2 candidates,#2551and#2552, both drafts from the same author reworking row-limit handling inMSSqlConnector.query. Neither touches connection setup, autocommit, or transactions.Summary by CodeRabbit