Skip to content
45 changes: 40 additions & 5 deletions mssql_python/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1703,16 +1703,51 @@ def __enter__(self) -> "Connection":
logger.info("Entering connection context manager.")
return self

def __exit__(self, *args: Any) -> None:
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
Comment thread
gargsaumya marked this conversation as resolved.
"""
Exit the context manager.

Closes the connection when exiting the context, ensuring proper
resource cleanup. This follows the modern standard used by most
database libraries.
Implements commit-on-success / rollback-on-exception semantics:
- If the block exits cleanly and autocommit is off, the transaction
is committed.
- If an exception is raised and autocommit is off, the transaction
is rolled back.
- The connection is always closed when leaving the block.

If commit() fails on clean exit, the connection is closed and the
commit exception is raised. On exception exit, cleanup failures
(rollback or close) are suppressed so the original user exception
propagates unchanged.
"""
if not self._closed:
if self._closed:
return
try:
if not self.autocommit:
if exc_type is None:
self.commit()
else:
self.rollback()
except Exception:
Comment thread
bewithgaurav marked this conversation as resolved.
try:
self.close()
except Exception:
Comment thread
bewithgaurav marked this conversation as resolved.
logger.warning(
"Failed to close connection after failed "
"commit/rollback in context manager.",
exc_info=True,
)
if exc_type is None:
raise
return
try:
self.close()
except Exception:
if exc_type is None:
raise
logger.warning(
"Failed to close connection in context manager.",
exc_info=True,
)

def __del__(self) -> None:
"""
Expand Down
Loading
Loading