Пытаюсь переделать монолит в проект на Microsoft Orleans. В монолите реализован Outbox паттерн с помощью транзакции (pseudo):
using(var transaction = connection.BeginTransaction())
{
using(var entityCommand = connection.CreateCommand())
{
entityCommand.CommandText = "INSERT INTO dbo.Entities ()...."; //UPDATE
entityCommand.ExecuteNonQuery();
}
using(var messageCommand = connection.CreateCommand())
{
messageCommand.CommandText = "INSERT INTO dbo.EntitiesOutbox ....";
messageCommand.ExecuteNonQuery();
}
transaction.Commit();
}
В Orlean's транзакции поддерживаются только для IPersistentState и поэтому встречал предложения сделать сообщение для Outbox частью самого State'а сущности и обрабатывать "провайдером". Что мне кажется совсем неправильно.
В рамках транзакции вызывать IGrainService который будет Insert'ить сообщения в Outbox и транзакция Commit'иться если прошло успешно... Но IGrainService будет работать не в scope'е транзакции ....
Ещё вариант - это использовать IGrainService в качестве репозитория для State Storage Provider'а => те ReadStateASync() читает, а запись будет непосредственно вызовом IGrainService.Save(IState), но тогда в репозитории надо будет хардкодить события, которые необходимо кидать в Outbox.. А это хотелось бы делать всё таки в Grain'е.
Как реализовать Outbox паттерн в Microsoft Orleans?
P.S. Можно ли тоже самое реализовать в Akka.NET ?