Forum Discussion
Work Around for getting snapshot isolation error in warehouse?
I have update statments at warehouse end which executes from ADF pipeline, we receive snapshot isolation errors on big tables where we ran udpate statments, wanted to understand if there are any better ways to handle these issues, as these are intermittent and does not happen when we ran re-try job of the same procedure, but in the process it starts the whole executions again and again, how can we avoid it in fabric warehouse?
Hi AnmolGan81 , Thank you for reaching out to the Microsoft Community Forum.
Yes, you can handle snapshot isolation errors in Fabric Warehouse by using ADF’s built-in retry on the Stored Procedure activity, no need to modify your SQL procedures. Just go to the activity’s Settings tab in ADF and set a retry count and interval. This will automatically re-run the procedure if it fails due to transient issues like error 3960, without restarting the whole pipeline.
Pipelines and activities - Azure Data Factory & Azure Synapse | Microsoft Learn
Built-in policy definitions - Azure Data Factory | Microsoft Learn
18 Replies
- v-hashadapu
Community Support
Hi AnmolGan81 , Thank you for reaching out to the Microsoft Community Forum.
You're hitting snapshot isolation errors in Fabric Warehouse because concurrent transactions are trying to update the same rows or overlapping partitions. Fabric uses snapshot-based concurrency with no user-configurable isolation level, so when row versions conflict, one transaction fails. This is expected behavior under heavy update workloads.
Stop using wide UPDATE statements and switch to MERGE with a filter that limits updates to only changed rows. This cuts down lock duration and write contention, reducing the chance of version conflicts. Avoid retrying the full pipeline in ADF. Instead, isolate the update step in its own activity with ADF’s built-in retry. If needed, you can also handle retry in T-SQL using TRY...CATCH with a delay and specific handling for error 3960.
If you're updating large volumes and still hitting contention, split the updates into smaller batches using a key or timestamp. For even heavier loads, consider moving to Delta Lake in a Lakehouse, which offers ACID transactions with better concurrency support via Spark.
Transactions in Warehouse Tables - Microsoft Fabric | Microsoft Learn
Performance Guidelines - Microsoft Fabric | Microsoft Learn
MERGE (Transact-SQL) - SQL Server | Microsoft Learn
- AnmolGan81
Advocate II
We cannot stop using updates as these are part of our existing framework that contains SCD1 & SCD2 logics, neither we can run them sepretely inside the ADF, we have seen this behaviour happening for tables with huge datasets, and we dont have same procedures being executed from anywhere when these pipelines are running, is there anyway to check this what might be blocking.
For changing UPDATE statments to Merge is a huge thing but are you sure that this should resolve the issue that we are facing?
With respect to try and catch can you point me in the right direction with some blogs or examples that can help us in implementing this and further testing this stored procuedre?
- v-hashadapu
Community Support
Hi AnmolGan81 , Thank you for reaching out to the Microsoft Community Forum.
Even if no other process is running the same procedure, snapshot isolation errors in Fabric Warehouse can still occur when updates touch large volumes of data. These aren’t blocking issues, they’re caused by Fabric’s internal row versioning. Under snapshot isolation (which is always enforced in Fabric), write-write conflicts can arise if the version store is overloaded or when overlapping updates happen, even within a single session.
Fabric doesn't expose lock-level views, but you can monitor execution behavior using sys.dm_pdw_exec_requests and sys.dm_pdw_request_steps to check for slow or stuck queries and get insight into execution stages.
Switching from UPDATE to MERGE only helps if it reduces the number of rows being written, for example, by excluding unchanged rows. If your current UPDATE already filters effectively, switching syntax won’t eliminate the issue.
The most practical mitigation is to add retry logic inside the stored procedure, targeting transient error 3960. Here’s a clean example:
DECLARE @retryCount INT = 0, @maxRetries INT = 3;
WHILE @retryCount < @maxRetries
BEGIN
BEGIN TRY
EXEC YourSCDProcedure;
BREAK;
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 3960
BEGIN
SET @retryCount += 1;
WAITFOR DELAY '00:00:05';
END
ELSE
BEGIN
THROW;
END
END CATCH
END
Please refer to the below documentation:
TRY...CATCH (Transact-SQL) - SQL Server | Microsoft Learn
Transactions in Warehouse Tables - Microsoft Fabric | Microsoft Learn
Performance Guidelines - Microsoft Fabric | Microsoft Learn
Read Transactions and Isolation Levels in Fabric W... - Microsoft Fabric Community