First of all I work with C# (ASP.Net Core 3.1 in this case) but the question is more generic about design pattern.
So I ran into an issue using the repositories pattern. I needed to have transactions for my repositories and I found the UnitOfWork pattern that I was not aware of. I implemented it in the way that while EF Core SaveChanges is like a transaction itself when there is only one call to SaveChanges (which should be the case with the UnitOfWork if possible) then I don't need to have a "proper transaction". All was working fine than I need to do something basic : I create an entity in the DB and then create an email in which I need the ID of this entity.
The process is the following :
- Create the entity
- Create the email content
- Save the entity
- Send the email
The issue is that the ID of the entity is generated on the insert in the DB and if I call SaveChanges after creating the email content the ID is not set. But if the creation of the email content fail I don't want the insert to be done in the DB. So I was like "hum, I really need a transaction after all". So I did the following in my UnitOfWork:
public async Task OpenTransaction()
{
if (_dbTransaction == null)
{
_dbTransaction = await _dbContext.Database.BeginTransactionAsync().ConfigureAwait(false);
}
}
/// <inheritdoc />
public async Task CommitTransaction()
{
if (_dbTransaction != null)
{
try
{
await _dbTransaction.CommitAsync().ConfigureAwait(false);
}
catch (Exception)
{
await _dbTransaction.RollbackAsync().ConfigureAwait(false);
_dbTransaction.Dispose();
_dbTransaction = null;
throw;
}
}
_dbTransaction.Dispose();
_dbTransaction = null;
}
And the my process become the following :
- Open a transaction
- Create the entity
- Create the email content
- Commit the transaction
And it's working but I'm afraid that I introduced some kind of "anti-pattern".
Does someone had a similar issue? What do you think of the solution I choose? Is there a better way or another pattern to solve this ?
Thanks a lot
Aucun commentaire:
Enregistrer un commentaire