Skip to content

Conversation

@MikeAlhayek
Copy link
Collaborator

No description provided.

@xeron333
Copy link

xeron333 commented Dec 18, 2025

I tried to validate the thread-safety behavior introduced/affected by this PR by writing a dedicated test using
concurrent access on the same session.

Example:

`[Fact]`
`public` `async` `Task` `InvalidOperation()`
`{`
    `await` `using` `var` `session` `=` `_store.CreateSession();`
    `var` `p1` `=` `new` `Person();`
    `var` `p2` `=` `new` `Person();`
    `var` `p3` = `new` `Person();`

    `await` `session.SaveAsync(p1);`
    `await` `session.SaveAsync(p2);`
    `await` `session.SaveAsync(p3);`
    `await` `session.SaveChangesAsync();`

    `await` `Assert.ThrowsAsync<InvalidOperationException>(async` `()` `=>`
    `{`
        `await` `Task.WhenAll(`
            `Task.Run(()` `=>` `session.SaveChangesAsync()),`
            `Task.Run(()` `=>` `session.GetAsync<Person>(p1.Id))`
        `);`
    `});`
`}`

I ran this test with SQLite with EnableThreadSafetyChecks = true and false, and observed no difference: no exception
 is thrown in either case.

Unless I missed something, I don’t see a behavior change here regarding concurrent access detection.

Additional note: running the same test against SQL Server (2017) does throw an InvalidOperationException, while SQLite
 does not. This seems to be provider-specific rather than related to the changes in this PR.

After further testing, concurrent access on the same session does not consistently throw an exception.
The behavior is provider- and timing-dependent, and exceptions cannot be relied upon for validating thread safety..with EnableThreadSafetyChecks = true and false

I also wrote this Valid test and there of course no exceptions (with EnableThreadSafetyChecks = true and false) :

`[Fact]`
`public` `async` `Task` `ValidOperation()`
`{`
    `await` `using` `var` `session` `=` `_store.CreateSession();`
    `var` `p1` `=` `new` `Person();`
    `var` `p2` `=` `new` `Person();`
    `var` `p3` `=` new `Person();`

    `await` `session.SaveAsync(p1);`
    `await` `session.SaveAsync(p2);`
    `await` `session.SaveAsync(p3);`

    `await` `session.SaveChangesAsync();`
    `var` `ex0` `=` `await` `Assert.ThrowsAsync<InvalidOperationException>(async` `()` `=>`
    `{`
        `await`
        `Task.Run(()` `=>` `session.GetAsync<Person>(p1.Id));`
    `});`
    `_output.WriteLine($"Exception` `Valid:` `{ex0.GetType().FullName}");`
    `_output.WriteLine($"Exception` `messageValid:` `{ex0.Message}");`
}
"Assert.Throws() Failure: No exception was thrown"
"Expected: typeof(System.InvalidOperationException)"

@xeron333
Copy link

To conclude on this PR, and after testing on both SQLite and SQL Server for public virtual async Task ShouldDetectThreadSafetyIssues():

I could not observe any functional difference compared to the original branch:

UseThreadSafetyChecks(bool) is simply a wrapper around EnableThreadSafetyChecks.

The exceptions, messages, and stack traces are identical.

Test outcomes are the same before and after the PR.

At this stage, the PR appears to mainly provide API refactoring / fluent configuration improvements, without introducing new behavior or additional test coverage.

Please let me know if there is an intended functional change or scenario I may have missed.

@sebastienros
Copy link
Owner

I could not observe any functional difference compared to the original branch:

I think that this is expected. The goal of this PR was to have the feature enabled for all our tests so we can detect more issues with the current code or the tests themselves. The flag ensures a session is not used concurrently by two threads. So ideally just setting it up should not fail any existing test. If it does then either we need to check the test is right, or there is a bug in yessql that it exposes.

@sebastienros
Copy link
Owner

I removed the EnableThreadSafetyChecks test:

  • at first it was actually disabling it, so it could not work
  • finally it was failing locally with corrupted connection strings, which is a side effect of the issue we were tracking, making the test useless

So since all the tests are running with the feature, I assume this is already well tested. At least covered by tests (not really ensuring it actually works).

@sebastienros
Copy link
Owner

I also renamed the extension methods as I felt that Use was not appropriate. We currently use this for custom implementations of services.

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.

4 participants