несколько репозиториев, совместно использующих один и тот же контекст, вызывающий операцию savechanges - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть архитектура Web API следующим образом:

Контроллер -> Службы -> Хранилища

Зависимость вводится в использование Unity фреймворка через шаблон инжектора конструктора.

У меня есть что-то похожее в моем проекте:

public class OrderService : IOrderService
{
    private readonly IOrderRepo _orderRepo;
    private readonly IProductRepo _prodRepo;

    public OrderService(IOrderRepo orderRepo, IProductRepo prodRepo)
    {
        _orderRepo = orderRepo;
        _prodRepo = prodRepo;
    }

    public void DoSomething()
    {
        _orderRepo.Update();
        _prodRepo.Insert();
    }
}

public class OrderRepo : IOrderRepo
{
    private readonly CreditPortalContext _context;

    public OrderRepo(MyContext context)
    {
        _context = context;
    }

    public void Update()
    {
        //Do something
        _context.SaveChanges();
    }
}

public class ProductRepo : IProductRepo
{
    private readonly CreditPortalContext _context;

    public ProductRepo(MyContext context)
    {
        _context = context;
    }

    public void Insert()
    {
        //Do something
        _context.SaveChanges();
    }
}

Теперь OrderService вызывает два разных метода хранилища для выполнения какой-либо операции с базой данных.

Что мне нужно, так это если в методе _prodRepo.Insert(); произойдет сбой, он также должен выполнить откат _orderRepo.Update();.

Я слишком далеко в этом проекте, поэтому не могу выполнить значительные изменения архитектуры вэта точка.Кроме того, объект context создается только один раз (с использованием Unity HierarchicalLifetimeManager)

Есть ли в любом случае, я могу достичь этого?

1 Ответ

0 голосов
/ 27 февраля 2019

это вовсе не идеальная ситуация, и я боюсь, что вам придется проявить креативность.

Вы не можете реально откатить заявление, которое уже было совершено, но вы можете сделатьчто-то еще.

Итак, ситуация такова: у вас есть 2 вызова, вызов A и вызов B.

вызов A успешно завершается.вызов B завершается неудачно, и вы хотите выполнить откат A.

Я предлагаю выполнить первый коммит в другой таблице.

Создайте копию вашей таблицы в базе данных и зафиксируйте ваши данные там.если B преуспевает, тогда вы вводите другую команду для переноса данных в основную таблицу, где она должна быть.Если произойдет сбой B, вы просто удалите данные из второй таблицы, и ваша основная таблица останется нетронутой.

Это можно сделать с помощью хранимой процедуры, которую вы можете вызвать, присвоить ей идентификатор записи и затемон обновляет основную таблицу, используя строку из второй таблицы.Вы можете легко вызвать хранимую процедуру из структуры сущностей, чтобы ее часть не была проблемой.

Итак, нижняя строка, используйте место временного хранения и перемещайте данные только тогда, когда ваш второй вызов завершится

...