-
|
I'm working on this issue: #3879 . I have implementation ready, but when i test it - throwing inside transaction like this: await testRepository.RunInTransaction(async token =>
{
await testRepository.Create(entity, cancellationToken: token);
await messageBrokerProcessor.DepositPostAsync(new MessageBrokerTestEvent
{
Name = request.Name
}, cancellationToken: token);
throw new InvalidOperationException("Test exception");
}, cancellationToken: context.CancellationToken);does not cancel the outbox entry - it is send to message broker. I'm trying to poke around the code to find out how automatic the transaction handling should be, but i cannot find anything specific. Documentation here: https://brightercommand.gitbook.io/paramore-brighter-documentation/guaranteed-at-least-once/efcoreoutbox suggests that all i need to do is to create transaction from dbContext and Post message inside. But it's clearly not working for me, i've added breakpoints inside my EFTransactionProvider and it's not being called anywhere. Is that a bug or maybe i need to use transaction explicitly, because this sample suggests that i should inject and use |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 11 replies
-
|
Maybe @iancooper can help you on this |
Beta Was this translation helpful? Give feedback.
-
|
I am working on some updates for V10 documentation, hopefully it will help. Some assumptions that we make:
To get hold of the context for your transaction we abstract your transaction behind the transaction provider. There are tailored to the persistence method you are using (EF Core, Dapper, DynamoDb) We recommend you to make that a dependency of your handler, so that it is injected into your handler (we do this work for you, once you tell us what it will be at configuration). But, what you must do is pass the transaction provider to us via the DepositPost call. (In principle, you could create an instance of the transaction provider, there in the handler, and pass that in, over using DI, YMMV on which works better). (The version of DepositPost that does not take a transaction provider supports you just defaulting to an in-memory outbox) Once you pass it in, we can use its connection to write to our Outbox, safely within your transaction. (In principle, with something like DynamoDb, we could just use a global connection as there is no transaction-connection affinity, but we hit problems with this in V10, and most likely won't re-address until V11) So, the key here is that you must pass the transaction provider to DepositPost so that we can use your connection, and an easy way to do that is via DI. |
Beta Was this translation helpful? Give feedback.
Generally, the pain point here became "scope". EF requires that we use a scoped lifetime. That means everything that depends on that transaction provider has to use a scoped lifetime.
A scoped command processor creates pain points around caching pipelines and producers. Now we can offload those to something that holds the singleton, etc. But generally, because we are often downstream of ASP.NET, with no control over the scope, we don't benefit from that scope in the same way that ASP.NET does; it is just propagated to us. It is much easier for us to declare the handlers as having a scoped lifetime and take that dependency.
We tried the "just inject into the CP strategy," but our experienc…