✅ do i use BeginTransaction() correctly?

hi, am i using BeginTransaction() correctly? here is my code:
using (var context = dbContextFactory.CreateDbContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
var offer = await context.Offers.Where(x => x.OfferId == tableEntity.Offer.OfferId).FirstOrDefaultAsync();
if (offer is not null)
{
tableEntity.PendingOffer.Id = Guid.NewGuid().ToString();
tableEntity.PendingOffer.OfferId = tableEntity.Offer.OfferId;
tableEntity.PendingOffer.BuyerId = User.Id;
tableEntity.PendingOffer.SellerId = ProfileUser.Id;
context.PendingOffers.Add(tableEntity.PendingOffer);
await context.SaveChangesAsync();
StateHasChanged();
transaction.Commit();
}
else
{
tableEntitiesHandler.OfferTableEntities.Remove(tableEntity);
}
}
catch
{
transaction.Rollback();
}
}
}
using (var context = dbContextFactory.CreateDbContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
var offer = await context.Offers.Where(x => x.OfferId == tableEntity.Offer.OfferId).FirstOrDefaultAsync();
if (offer is not null)
{
tableEntity.PendingOffer.Id = Guid.NewGuid().ToString();
tableEntity.PendingOffer.OfferId = tableEntity.Offer.OfferId;
tableEntity.PendingOffer.BuyerId = User.Id;
tableEntity.PendingOffer.SellerId = ProfileUser.Id;
context.PendingOffers.Add(tableEntity.PendingOffer);
await context.SaveChangesAsync();
StateHasChanged();
transaction.Commit();
}
else
{
tableEntitiesHandler.OfferTableEntities.Remove(tableEntity);
}
}
catch
{
transaction.Rollback();
}
}
}
so after the offer has been checked it can still be deleted afterwards. By using BeginTransaction() i can have every condition (that is inside the transaction using block) atomic, if something changes, for example my offer gets deleted, SaveChangesAsync throws an exception and calls the Rollback function. right?
4 Replies
Qui-Gon Jinn
Qui-Gon JinnOP2y ago
i tested my code multiple times but unfortunately the pendingoffer still gets added to the database, even if the offer has been deleted. I could use "IsolationLevel.Serializable" but that does the opposite what i want to do. this isolationlevel prevents the offer to be deleted until the transaction is completed. but i dont want to lock it, i want others to delete the offer anytime they want and if the offer is deleted right after the offer null check i want the transaction detect it and dont add the data to the database
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Qui-Gon Jinn
Qui-Gon JinnOP2y ago
@TeBeCringe yes i am using blazor server app and i use dependency injection, however i often had concurrency issues ("the 'second operation started on the same dbcontext exception' ") when i only had one dbcontext instance at the time. so this is why i am adding a dbcontextfactory in the program.cs like this:
builder.Services.AddDbContextFactory<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDbContextFactory<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
AddDbContextFactory creates a factory with lifetime singleton by default, unless it is defined otherwise. then i am injecting the factory in my razor component like this:
@inject IDbContextFactory<ApplicationDbContext> dbContextFactory;
@inject IDbContextFactory<ApplicationDbContext> dbContextFactory;
with this i can create a dbcontext wherever i want without worrying about dbcontext concurrency because they work independently of each other. i also have components where i create a dbcontext from the factory and use it in the whole component. regarding my actual issue i think i should just use "IsolationLevel.Serializable" this way i avoid that an offer can be deleted while the transaction is running. i also could have something like : (offer exists) ? context.SaveChanges() : return; instead of having the nullcheck inside the ifstatement
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server