Como dar suporte a métodos assíncronos em um TransactionScope com Microsoft.Bcl.Async no .NET 4.0?
Eu tenho um método semelhante a:
public async Task SaveItemsAsync(IEnumerable<MyItem> items)
{
using (var ts = new TransactionScope())
{
foreach (var item in items)
{
await _repository.SaveItemAsync(item);
}
await _repository.DoSomethingElse();
ts.Complete();
}
}
Claro que isso tem problemas porqueTransactionScope
não funciona bem com assíncrono / espera.
Falha com umInvalidOperationException
com a mensagem:
"Um TransactionScope deve ser descartado no mesmo encadeamento que foi criado."
eu leio sobreTransactionScopeAsyncFlowOption
noesta resposta, que parece ser exatamente o que eu preciso.
No entanto, para este projeto em particular, tenho um requisito difícil de oferecer suporte ao .Net 4.0 e não posso atualizar para o 4.5 ou 4.5.1. Assim, o comportamento assíncrono / espera no meu projeto é fornecido peloPacote Microsoft.Bcl.Async NuGet.
Não consigo encontrarTransactionScopeAsyncFlowOption
neste ou em qualquer outroPacote OOB. Estou apenas sentindo falta em algum lugar?
Se não estiver disponível, existe uma alternativa para alcançar o mesmo resultado? Ou seja, eu gostaria que o escopo da transação fosse concluído ou revertido corretamente, apesar de cruzar threads com continuações.
Eu adicioneiDoSomethingElse
no exemplo acima para ilustrar que pode haver várias chamadas a serem feitas no escopo da transação, simplesmente passar todos os itens para o banco de dados em uma chamada não é uma opção viável.
Caso isso importe, o repositório usa o ADO.Net direto (SqlConnection
, SqlCommand
, etc) para gravar em um SQL Server.
ATUALIZAR
Eu pensei que tinha uma solução que envolvia a retirada do System.Transactions.dll do .Net 4.5.1 e a inclusão no meu projeto. No entanto, descobri que isso funcionava apenas na minha caixa de desenvolvimento, porque já tinha a 4.5.1 instalada. Não funcionou ao implantar em uma máquina com apenas .Net 4.0. Apenas deu umaMissingMethodException
. Estou procurando uma solução que funcione em uma instalação .Net 4.0.