-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Fix flaky test by restructuring to avoid concurrent TransactionScope operations #37101
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
base: main
Are you sure you want to change the base?
Conversation
…sactionScope.Complete() Co-authored-by: cincuranet <[email protected]>
Co-authored-by: cincuranet <[email protected]>
|
@copilot Show me itemized steps for both tasks that lead to |
Here are the itemized steps for both scenarios that lead to Scenario 1: resetFirst = false (Task 0 calls scope.Complete(), Task 1 calls ResetState()) Task 0 (scope.Complete()):
Task 1 (ResetState()):
Scenario 2: resetFirst = true (Task 0 calls ResetState(), Task 1 calls scope.Complete()) Same as Scenario 1 but with tasks reversed - Task 1 gets the exception when it tries to call The race condition occurs because |
|
@copilot Instead of catching the exception, fix the root cause. |
The original test was calling scope.Complete() concurrently with ResetState(), which caused ObjectDisposedException due to TransactionScope API limitations. The root cause was that the test was testing the wrong scenario - it was mixing user code (scope.Complete()) with internal EF Core operations (ResetState()). Fixed by restructuring the test to: 1. Complete and dispose the TransactionScope on the main thread in a using block 2. Then test the actual race condition: HandleTransactionCompleted callback (triggered by scope disposal) vs ClearTransactions (called by ResetState()) This properly tests the thread-safety between HandleTransactionCompleted and ClearTransactions without hitting TransactionScope API constraints. Co-authored-by: cincuranet <[email protected]>
Fixed the root cause in commit aeaba76. The issue was that the test was calling The test now properly tests the actual race condition (HandleTransactionCompleted vs ClearTransactions) by:
Verified with 100 consecutive successful test runs. |
The test
HandleTransactionCompleted_with_concurrent_ClearTransactions_is_thread_safewas failing intermittently due to callingTransactionScope.Complete()concurrently withResetState(), which violatedTransactionScopeAPI constraints and causedObjectDisposedException.Root Cause
The original test design mixed user code (
scope.Complete()) with internal EF Core operations (ResetState()) in a concurrent manner that theTransactionScopeAPI doesn't support. This was causingObjectDisposedExceptionwhen the scope's underlying transaction was being cleared on another thread.Solution
Restructured the test to properly test the actual race condition without violating
TransactionScopeAPI constraints:TransactionScopeon the main thread within a using blockHandleTransactionCompletedcallback (triggered by scope disposal) andClearTransactions(called byResetState()) on a background threadThis approach correctly tests the thread-safety between
HandleTransactionCompletedandClearTransactionsas originally intended, without hittingTransactionScopeAPI limitations.Testing
Fixes #37086
Original prompt
Microsoft.EntityFrameworkCore.RelationalConnectionTest.HandleTransactionCompleted_with_concurrent_ClearTransactions_is_thread_safeis flaky #37086💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.