-
Notifications
You must be signed in to change notification settings - Fork 290
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
ExecuteScalar does not always raise an exception when selected as deadlock victim #458
Comments
This error interacts poorly with EF Core which does not check the transaction state before executing the next command in the batch. Every command after the failed one is executed outside a transaction, thus committing only some of the changes in the batch with no possibility of rollback. There's no indication that the transaction has been aborted until It would be nice if attempting to use an aborted/completed transaction on a command would raise an exception, but I guess this is a known limitation? |
Hi @deadalusai I was able to reproduce the issue with v1.1.1 but when I tried with latest 'master' branch and also with 2.0.0-preview1 version of driver, this issue is not reproducible. I think the PR that fixed async deadlock issues also covered this case (#349) ?
Could you give the new package a try and let us know? |
However I do see normal exception captured as below:
|
Hi @cheenamalhotra, thanks for investigating. I was able to reproduce the error using
Edit: I reproduced the error against SQL Server 12.0.4100.1 - I'll attempt a repro on my other machine with a more recent version of SQL Server as well some time today. |
Reproduced using |
Hi @cheenamalhotra - any update on this issue? An observation we made is that the command which ends up being chosen as deadlock victim and causing the transaction to be aborted also successfully returns a scalar result. See thread
The SequenceId it returns is correct, though it never ends up committed to the table. This could point to why |
After running multiple times I do see 3 mixed cases..
On further testing, this is not only in .NET Core, but also reproducible with .NET Framework and with both drivers System.Data.SqlClient and Microsoft.Data.SqlClient. However, I would also investigate more about executing multiple commands in "RepeatableRead" Isolation Level, and if this case is absolutely valid. |
Hi @cheenamalhotra - any update on this issue? |
Hi @deadalusai Thanks for your patience. We'll get back to investigating this soon! |
Hi @cheenamalhotra - any update on this issue? |
Any update or work around on this? |
We've had some success with prepending something like the following before every insert/update/delete SQL operation: IF (@@TRANCOUNT = 0) THROW 51000, 'Not running in a transaction.', 1; For SqlClient you just prepend it to the command text. |
Hello! Tested @deadalusai's example with SqlClient 3.0, the problem is still reproducible. Did a small research, and it looks like SqlClient reports the error depending on when exactly that error is read - either on |
Describe the bug
We have encountered an issue in production where
ExecuteScalar
run in context of a RepeatableRead transaction intermittently fails to raise an exception when SQL Server selects it as a deadlock victim and rolls back the transaction. The transaction state is correctly set toAborted
, but the lack of an exception confuses application code and libraries like EF Core and who assume (fairly reasonably) that no exception means success.Additionally, ExecuteScalar is returning the value that would be expected for a successful transaction even though the transaction has been rolled back.
The issue does not seem to occur when using
ExecuteReader
orExecuteNonQuery
.I have a reduced repro case which consistently reproduces the error on SQL Server 12 and 13, tested across multiple machines. The issue reproduces with System.Data.SqlClient/dotnet core 2.1 and Microsoft.Data.SqlClient/dotnet core 3.1.
To reproduce
Clone the repository https://github.com/deadalusai/SqlClient-Aborted-Transaction-Repro
Create a new database using the
ZombieDb.sql
scriptRun the test program:
For .NET Core 3.1 with Microsoft.Data.SqlClient:
For .NET Core 2.1 with System.Data.SqlClient:
Press any key to start testing for the error case. The test will run until it reproduces the issue or times out.
Expected behavior
A SqlException to be raised when a command is selected as a deadlock victim.
Further technical details
Microsoft.Data.SqlClient version: 1.1.1
System.Data.SqlClient version: 4.8.1
.NET target: .NET Core 3.1, .NET Core 2.1
SQL Server version: SQL Server 2017, SQL Server 2016
Operating system: Windows 10
The text was updated successfully, but these errors were encountered: