Saving to database problem in Unit of Work
Is there an existing issue for this?
- [X] I have searched the existing issues
Description
I found an interesting bug that I'm struggling to detect and explain it here. I hope I can explain it clearly. The main suspect of the bug is Unit Of Work. It works differently according to count of records to be saved to database. Because of this difference, some records are not saved to DB. Let me explain with an example.
I want to save an Invoice to database. Meanwhile, I want to save the Client(customer) and Lines (Invoice lines) of the Invoice (at the same time).
I've been using a method like that to save both Customer (MasterClient), Invoice and InvoiceLines together. (I simplified the method)
using (var uow = _unitOfWorkManager.Begin(true, false))
{
#region MasterClient
MasterClient masterClient = new MasterClient(_guidGenerator.Create())
{
Name = eInvoice.invoice.Name,
Surname = eInvoice.invoice.Surname,
Title = eInvoice.invoice.Title,
};
await _masterClientRepository.InsertAsync(masterClient);
#endregion
#region Invoice
await _invoiceRepository.InsertAsync(invoice);
#endregion
#region Invoice Lines
List<InvoiceLine> invoiceLineItems = new List<InvoiceLine>();
foreach (var item in eInvoice.invoiceLines)
{
item.MasterClientId = masterClient.Id;
item.InvoiceId = invoice.Id;
var lineItem = new InvoiceLine(_guidGenerator.Create());
_objectMapper.Map<InvoiceLineDto, InvoiceLine>(item, lineItem);
var invoiceLine = await _invoiceLineRepository.InsertAsync(lineItem);
}
#endregion
result.value = invoice;
await uow.CompleteAsync();
//IMPORTANT => I will use other services here, like background job managers. So, invoice have to be saved to db before these services.
}
This method has saved over 100.000 invoices to DB without a problem until the last week. I discovered that it doesn't save an invoice data to database. I checked the incoming request data and everything seems good, but it can not be saved. I debugged the code but there was no error and it looked saving to database successfully. But when I check the database table, there was no record. I also tracked the SQL Server Profiler but there wasn't any error or rollback. Then I started comparing the request with successful ones previously and modifying the request data.
Finally I found an interesting thing: If the count of invoice lines is 35, invoice is not saved to database while invoice lines are saved. (The request has 35 invoice lines)
I tried from 1 to 34 one by one, all of them are saved successfully. (Customer, Invoice and InvoiceLines). If the count of Invoice Lines is 35 => Customer and InvoiceLines are saved, Invoice is not saved. If the count of Invoice Lines is 36, 37 , 38 => Customer and Invoice are saved, InvoiceLines are not saved. If the count of Invoice Lines is 39 and above => All of them are saved successfully.
I know it sounds very strange, but I couldn't find a logical explanation.
I found a workaround for this problem: If I make autosave of inserting MasterClient to true, then everything works good. But I don't want to use autoSave method as it is not recommended with the UOW in the ABP docs also. (https://docs.abp.io/en/abp/latest/Unit-Of-Work#alternative-to-the-savechanges)
await _masterClientRepository.InsertAsync(masterClient,true);
I uploaded the sample project to here with the Postman collection. (It has one request with 35 invoice lines) https://github.com/omer-repo/ACME.POC3
Reproduction Steps
No response
Expected behavior
No response
Actual behavior
No response
Regression?
No response
Known Workarounds
No response
Version
7.3.2
User Interface
Blazor
Database Provider
EF Core (Default)
Tiered or separate authentication server
None (Default)
Operation System
Windows (Default)
Other information
No response
hi
Can you test your code in a unit test method?
This method has saved over 100.000 invoices to DB without a problem until the last week. I discovered that it doesn't save an invoice data to database. I checked the incoming request data and everything seems good, but it can not be saved. I debugged the code but there was no error and it looked saving to database successfully. But when I check the database table, there was no record. I also tracked the SQL Server Profiler but there wasn't any error or rollback. Then I started comparing the request with successful ones previously and modifying the request data.
I believe you have encountered the same problem as me. See https://github.com/abpframework/abp/issues/15816.
Try removing this line:
app.UseUnitOfWork();
https://github.com/omer-repo/ACME.POC3/blob/master/src/ACME.POC3.HttpApi.Host/POC3HttpApiHostModule.cs#L202
@gdlcf88 , I removed but same thing happened. I think it is due to I'm already creating a UOW in the AppService.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
I'll add test, but I think it should be an integration test
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.