Edition 0 Updated to asp. Net core 0


null );  });  });  Execution strategies and explicit transactions using BeginTransaction



Yüklə 11,82 Mb.
Pdf görüntüsü
səhifə253/288
tarix12.07.2023
ölçüsü11,82 Mb.
#136458
1   ...   249   250   251   252   253   254   255   256   ...   288
NET-Microservices-Architecture-for-Containerized-NET-Applications

null
); 
}); 
}); 
Execution strategies and explicit transactions using BeginTransaction 
and multiple DbContexts 
When retries are enabled in EF Core connections, each operation you perform using EF Core becomes 
its own retryable operation. Each query and each call to 
SaveChanges
will be retried as a unit if a 
transient failure occurs. 
However, if your code initiates a transaction using 
BeginTransaction
, you’re defining your own group 
of operations that need to be treated as a unit. Everything inside the transaction has to be rolled back 
if a failure occurs. 
If you try to execute that transaction when using an EF execution strategy (retry policy) and you call 
SaveChanges
from multiple DbContexts, you’ll get an exception like this one:
System.InvalidOperationException: The configured execution strategy 
‘SqlServerRetryingExecutionStrategy’ does not support user initiated transactions. Use th
e execution 
strategy returned by ‘DbContext.Database.CreateExecutionStrategy()’ to execute all the operations in 
the transaction as a retriable unit. 
The solution is to manually invoke the EF execution strategy with a delegate representing everything 
that needs to be executed. If a transient failure occurs, the execution strategy will invoke the delegate 
again. For example, the following code shows how it’s implemented in eShopOnContainers with two 
multiple DbContexts (_catalogContext and the IntegrationEventLogContext) when updating a product 
and then saving the ProductPriceChangedIntegrationEvent object, which needs to use a different 
DbContext. 
public
async Task 
UpdateProduct

[FromBody]CatalogItem productToUpdate) 

// Other code ...
var
oldPrice = catalogItem.
Price

var
raiseProductPriceChangedEvent = oldPrice != productToUpdate.
Price

// Update current product
catalogItem = productToUpdate; 
// Save product's data and publish integration event through the Event Bus
// if price has changed
if
(raiseProductPriceChangedEvent) 

//Create Integration Event to be published through the Event Bus
var
priceChangedEvent = 
new
ProductPriceChangedIntegrationEvent

catalogItem.
Id
, productToUpdate.
Price
, oldPrice); 


298 
CHAPTER 7 | Implement resilient applications 
// Achieving atomicity between original Catalog database operation and the
// IntegrationEventLog thanks to a local transaction
await _catalogIntegrationEventService.
SaveEventAndCatalogContextChangesAsync

priceChangedEvent); 
// Publish through the Event Bus and mark the saved event as published
await _catalogIntegrationEventService.
PublishThroughEventBusAsync

priceChangedEvent); 

// Just save the updated product because the Product's Price hasn't changed.
else

await _catalogContext.
SaveChangesAsync
(); 

Yüklə 11,82 Mb.

Dostları ilə paylaş:
1   ...   249   250   251   252   253   254   255   256   ...   288




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©azkurs.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin