How to fix Error 3970 on Windows Server 2025 / Windows 11

Troubleshooting Guide: SQL Server Error 3970

Why This Error Happens

Error 3970 occurs when multiple threads or processes attempt to issue conflicting commands (such as COMMIT, ROLLBACK, or BEGIN) against the same transaction simultaneously. This typically happens due to application code that reuses a connection or transaction object across multiple threads without proper synchronization, or when a previous command on the connection hasn’t fully completed (is still pending) before a new one is issued. In some cases, this is triggered by MARS (Multiple Active Result Sets) being improperly managed, or by an application timeout that fires a rollback while the original query is still executing.

Step-by-Step Resolution Guide

Step 1: Identify the Conflicting Session and Query

  • Open SQL Server Management Studio (SSMS) and run sp_who2 or query sys.dm_exec_requests to identify the session ID (SPID) throwing the error.
  • Check sys.dm_tran_active_transactions joined with sys.dm_tran_session_transactions to see if a single session has multiple open transactions.
  • Review the SQL Server error log at C:\Program Files\Microsoft SQL Server\MSSQL17.MSSQLSERVER\MSSQL\Log\ERRORLOG for the exact timestamp and context of the 3970 error.

Step 2: Audit Application Connection and Threading Logic

  • Verify the application is not sharing a single SqlConnection or SqlTransaction object across multiple threads concurrently.
  • Check the connection string for MultipleActiveResultSets=True — if present, ensure the application correctly awaits each command before issuing another on the same connection.
  • Look for mismatched BEGIN TRAN / COMMIT / ROLLBACK pairs in stored procedures, especially inside nested TRY/CATCH blocks where a ROLLBACK might fire while another batch is still active.

Step 3: Adjust Timeout and Retry Settings

  • Increase the command timeout value in the application’s connection settings (default is often 30 seconds) to prevent premature ROLLBACK calls from the client while a long-running query is still active.
  • Navigate to the application config (e.g., web.config or appsettings.json) and update the CommandTimeout property.
  • Implement application-level retry logic using exponential backoff rather than immediate transaction aborts.

Step 4: Restart the Affected Session or Service

  • If the issue persists on a specific SPID, kill the blocking session using KILL <SPID> in SSMS.
  • If the conflict is widespread, restart the SQL Server service via services.msc or run Restart-Service MSSQLSERVER in an elevated PowerShell prompt on Windows Server 2025.
  • Clear any orphaned connections by cycling the application’s connection pool (recycle the IIS App Pool or restart the service account).

Alternative or Verification Steps

  • To verify the fix, run the application’s transaction-heavy workflow under load and monitor sys.dm_tran_active_transactions to confirm no session shows multiple simultaneous “ACTIVE” transaction states.
  • If the error persists after code review, as a workaround, disable MARS in the connection string and ensure each thread opens its own dedicated SqlConnection instance.