I am trying to use TransactionScope in my SELECT query in EntityFramework Core 2.0. However I am getting this error : "Enlisting in Ambient transactions is not supported."
The idea is to implement "NO LOCK" option (I know it's not a good idea to have that option in place but it's vendor's requirement) when I do select query. So I added an extension method (Entity Framework with NOLOCK)
public static async Task<List<T>> ToListReadUncommittedAsync<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadUncommitted
}, TransactionScopeAsyncFlowOption.Enabled))
{
var result = await query.ToListAsync();
scope.Complete();
return result;
}
}
And also I have set to ignore the Ambient Transaction Warning.
public static void AddEntityFramework(this IServiceCollection services, string connectionString)
{
services.AddDbContextPool<OptomateContext>(options =>
{
options.UseSqlServer(connectionString);
options.ConfigureWarnings(x => x.Ignore(RelationalEventId.AmbientTransactionWarning));
});
}
And I have the query as below in my repository
public async Task<Patient> GetPatient(Common.Resources.Patient patient)
{
var pat = await Dbset.Where(x => string.Equals(x.Surname,patient.Surname,
StringComparison.CurrentCultureIgnoreCase)).ToListReadUncommittedAsync();
return pat.FirstOrDefault();
}
I understood that .Net Core 2.0 supports TransactionScope. but I am not sure why I am getting this exception.
Any idea why is this happening?
System.Transactions
are not supported yet in EF Core. The issue is tracked by #5595: Enable support for System.Transactions and is committed to be included in the next EF Core release 2.1. (Update: EF Core 2.1 indeed added System.Transactions support).
Until then, if the whole point is to use transaction with ReadUncommitted
, you can try using the explicit EF Core IDbTransaction
through BeginTransaction(DatabaseFacade, IsolationLevel)
extension method. Unfortunately it cannot be fully encapsulated like in your current custom extension method and requires passing the DbContext
instance:
public static async Task<List<T>> ToListReadUncommittedAsync<T>(this IQueryable<T> query, DbContext context)
{
using (var transaction = await context.Database.BeginTransactionAsync(System.Data.IsolationLevel.ReadUncommitted)) {
{
var result = await query.ToListAsync();
transaction.Commit();
return result;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With