Skip to content

Add IsDeadlockError#95

Merged
Giorgi merged 11 commits intomainfrom
Deadlock
Feb 19, 2026
Merged

Add IsDeadlockError#95
Giorgi merged 11 commits intomainfrom
Deadlock

Conversation

@Giorgi
Copy link
Owner

@Giorgi Giorgi commented Feb 18, 2026

No description provided.

pengweiqhca and others added 9 commits August 22, 2025 19:29
Oracle can trigger deadlocks (ORA-00060) using the classic cross-update
pattern. Unlike PostgreSQL/SQL Server which roll back the victim's entire
transaction, Oracle only rolls back the victim's statement. This requires
using Task.WhenAny instead of Task.WhenAll, then explicitly rolling back
the victim's transaction to release earlier locks and unblock the other
session.

https://claude.ai/code/session_01WusLPsCyEsDpSbp2Nm6Tkx
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds deadlock detection to the exception-classification pipeline by introducing an IsDeadlockError classifier hook, mapping provider-specific deadlock signals to a new DeadlockException, and adding cross-provider tests to validate the behavior.

Changes:

  • Add IsDeadlockError to IDbExceptionClassifier and implement it for SQLite, SQL Server, PostgreSQL, Oracle, and MySQL.
  • Introduce DeadlockException and wire deadlock classification through the interceptor/factory.
  • Add/override deadlock-focused tests and enable creating secondary DemoContext instances from stored options.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
EntityFramework.Exceptions/Tests/SqliteTests.cs Adds a SQLite-specific deadlock test case.
EntityFramework.Exceptions/Tests/OracleTests.cs Adds an Oracle-specific deadlock test case with Oracle-specific rollback handling.
EntityFramework.Exceptions/Tests/DemoContext.cs Stores DbContextOptions for creating secondary contexts in tests.
EntityFramework.Exceptions/Tests/DatabaseTests.cs Adds a provider-agnostic deadlock test (overridden by some providers).
EntityFramework.Exceptions/Common/Exceptions.cs Adds DeadlockException type.
EntityFramework.Exceptions/Common/ExceptionProcessorInterceptor.cs Adds deadlock classification path and enum value.
EntityFramework.Exceptions/Common/ExceptionFactory.cs Maps DatabaseError.DeadLock to DeadlockException.
DbExceptionClassifier/Sqlite/SqliteExceptionClassifier.cs Implements SQLite deadlock detection.
DbExceptionClassifier/SqlServer/SqlServerExceptionClassifier.cs Implements SQL Server deadlock detection (1205).
DbExceptionClassifier/PostgreSQL/PostgreSQLExceptionClassifier.cs Implements PostgreSQL deadlock detection (DeadlockDetected).
DbExceptionClassifier/Oracle/OracleExceptionClassifier.cs Implements Oracle deadlock detection (ORA-00060).
DbExceptionClassifier/MySQL/MySQLExceptionClassifier.cs Implements MySQL deadlock detection.
DbExceptionClassifier/Common/IDbExceptionClassifier.cs Adds IsDeadlockError to the classifier interface.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


await using var controlContext = new DemoContext(DemoContext.Options);
await using var transaction1 = await DemoContext.Database.BeginTransactionAsync();

Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BeginTransactionAsync() on DemoContext doesn’t acquire a lock in SQLite until a statement is executed. As written, transaction1 is never used, so the controlContext update may succeed and the test will fail/flap. Execute at least one read/write statement inside transaction1 (and keep it uncommitted) before running the conflicting controlContext ExecuteUpdateAsync, or use an explicit locking transaction mode to reliably trigger SQLITE_LOCKED_SHAREDCACHE.

Suggested change
// Execute a write operation within transaction1 to acquire a SQLite lock
await DemoContext.Products
.Where(c => c.Id == product.Id)
.ExecuteUpdateAsync(c => c.SetProperty(p => p.Name, "Test11"));

Copilot uses AI. Check for mistakes.
public bool IsNumericOverflowError(DbException exception);
public bool IsUniqueConstraintError(DbException exception);
public bool IsMaxLengthExceededError(DbException exception);
public bool IsDeadlockError(DbException exception);
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding IsDeadlockError as a new abstract interface member is a source/binary breaking change for any external IDbExceptionClassifier implementations. If this package is meant to be extensible, consider providing a default interface implementation returning false (net8 supports DIMs) to preserve compatibility, or ensure the package versioning reflects a breaking change.

Suggested change
public bool IsDeadlockError(DbException exception);
public bool IsDeadlockError(DbException exception) => false;

Copilot uses AI. Check for mistakes.
…r.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Giorgi Giorgi merged commit b4acd8e into main Feb 19, 2026
3 of 6 checks passed
@Giorgi Giorgi deleted the Deadlock branch February 19, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments