.Net Assertion failed: !realm.is_in_transaction() in test suite
SDK and version
SDK : .NET 8 Version: 11.6.1
Observations
- I'm not sure how to enable the backtrace
- This occurs when I run my test suite which uses an InMemoryConfiguration for the realms, but I cannot deterministically get this to occur. Some tests runs this never happens.
- In my code I use realm.Write for any transactions, some use an async delegate e.g await realm.Write(async () => {})
- The test suite makes a new InMemoryConfiguration with a unique identifier for each test case (use xunit with InMemoryConfiguration set in the constructor with a Guid.NewGuid() for identifier)
- Generally in my code I have
var realm = await Realm.GetInstanceAsync(_realmConfig);in each function that requires use of the realm.
Crash log / stacktrace
The active test run was aborted. Reason: Test host process crashed : D:\a\realm-dotnet\realm-dotnet\wrappers\realm-core\src\realm\object-store\impl\realm_coordinator.cpp:1160: [realm-core-13.23.4] Assertion failed: !realm.is_in_transaction()
Hi! Thanks for reporting this. I'm not sure but this may be .net specific issue. @nirinchev is it valid use of write with async?
The assertion essentially tells us that the realm thinks it's in the active transaction at the time when notifications for set version are about to be delivered. But it's hard to tell which code path triggered it exactly. @birdalicious could you run your code under the debugger and get us the stacktrace leading to this assertion?
You shouldn't use async delegates with Realm.Write() because the delegate itself is not awaited by the realm before it commits the transaction. It's generally not really optimal to call async methods while in a write, because you should release the write lock on the database as quickly as you can.
However, if you absolutely need to do that, a way to achieve it would be:
using (var transaction = realm.BeginWrite())
{
await SomeAsyncMethod();
transaction.Commit();
}
With what I said above I think the source of the assertion failure is the mismatch of transaction lifetimes that using an async write callback introduces. The .NET SDK could possibly provide an analyzer that highlights this as an anti-pattern, but the way to avoid it is to not use async delegates for the write callback.
Thank you both, I will make the necessary changes then. Thank you for the ehlp and hopefully it resolves my issue
@fealebenpae, @kiburtse I've removed any async code in the write transactions and the assertion still occurs. Unfortunately the error occurs so infrequently I haven't been able to get it to occur under the debugger
Can you try wrapping your tests inside a AsyncContext.Run(...) (this comes from the Nito.AsyncEx.Context nuget package). My hunch is that something in the xunit async context is behaving weirdly and it's not correctly serializing access to the Realm file.
I wrapped each test method with AsyncContext.Run(async () => {...}) and I still see the !realm.is_in_transaction() assertion error. To test I open my test explorer and run the tests with 'Run Until Failure' and monitor the test output. This will repeatedly run the tests an eventually I'll get the assertion error.
I don't think I've had it happen on a 'cold' test run since removing async functions from the write transactions.
Do you think you can create an isolated repro case that you could share with us? That'll help a lot with figuring out what's wrong.
This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.