Сколько я могу положить в одну транзакцию? - PullRequest
0 голосов
/ 19 сентября 2019

Это основано на «Должен ли я всегда использовать транзакции в nhibernate (даже для простого чтения и записи)?» .

Суть в том, что мы должны всегда использовать транзакцию, даже для простого получения, например:

using (ITransaction transaction = session.BeginTransaction())
{
    var printerJob2 = (PrinterJob) session.Get(typeof (PrinterJob), id);
    transaction.Commit();

    return printerJob2;
}

Давайте рассмотрим этот код:

User user = session.Get<User>(userId);
if(user == null) return UnAuthorizedResult();

Order order = session.Get<Order>(orderId);
if(order == null) return BadRequestResult();

session.Delete<Order>(order);
transaction.Commit();
return OkResult();

Я предполагаю, что я не собираюсь создавать новую транзакцию для каждойДоступ к БД, поскольку это становится довольно беспорядочным:

User user;
using (ITransaction transaction = session.BeginTransaction())
{
    user =  session.Get<User>(userId);
    transaction.Commit();
}
if(user == null) return UnAuthorizedResult();

Order order;
using (ITransaction transaction = session.BeginTransaction())
{
    order = session.Get<Order>(orderId);
    transaction.Commit();
}
if(order == null) return BadRequestResult();

using (ITransaction transaction = session.BeginTransaction())
{
    session.Delete<Order>(order);
    transaction.Commit();
    return OkResult();
}

Я предполагаю, что все это должно входить в одну транзакцию.Существуют ли ограничения для этого?
Сколько можно вложить в одну транзакцию, прежде чем она так или иначе "сломается"?

Ответы [ 2 ]

1 голос
/ 20 сентября 2019

Так что код из вашего примера - это некий беспорядок, заваленный открытием и закрытием транзакций в данном методе контроллера.Код в вашем примере в основном такой же, как и при отсутствии транзакций, потому что каждый шаг фиксирует себя сам.Я предполагаю, и приложение MVC, потому что я вижу OKResult в конце вашего кода.

Транзакции являются атомными единицами работы.Если у вас есть 3 шага и один из них неудачен, все должно быть откачено до последнего известного состояния до начала транзакции.В веб-сценарии это обычно запрос.Вы увидите много информации, если вы Google "сессии на запрос" nhibernate.С учетом сказанного я делаю пару вещей, чтобы убедиться, что я придерживаюсь этого шаблона.

В global.asax у меня есть эти вспомогательные методы

    public static ISession CurrentSession
    {
        get { return (ISession) HttpContext.Current.Items[Sessionkey]; }
        private set { HttpContext.Current.Items[Sessionkey] = value; }
    }

    protected void Application_BeginRequest() { CurrentSession = SessionFactory.OpenSession(); }

    protected void Application_EndRequest()
    {
        if (CurrentSession != null)
            CurrentSession.Dispose();
    }

Тогда у меня также есть этот атрибут, которыйЯ могу использовать его на уровне метода или контроллера, чтобы гарантировать, что каждое действие контроллера является транзакционно обоснованным

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class TransactionAttribute : ActionFilterAttribute
{
    private ITransaction Transaction { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Transaction = MvcApplication.CurrentSession.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (!Transaction.IsActive)
            return;

        if (filterContext.Exception == null)
        {
            Transaction.Commit();
            return;
        }

        Transaction.Rollback();
    }
}

И теперь мой код транзакции довольно хорошо содержится и не должен быть засорен во всех ваших методах контроллера.

1 голос
/ 19 сентября 2019

Вы используете транзакции, когда хотите, чтобы все обновления были успешными или все провалились.Как правило, вещи начинают отходить от него как способа действия и к операциям, которые терпимы к сбоям, выбирают, где они остановились при повторной попытке (вместо вставки дублирующих записей - ищите идемпотентность) и т. Д., И, как правило, более щадящиемир, полный латентности, кратковременной и нестабильной сетевой надежности, разрозненных систем и неспособности устанавливать объединяющие транзакции (поиск саг) и т. д., но по сути вы используете транзакцию, когда хотите, чтобы она была, как если бы это была операция с одним попаданием, котораясработало или нет.

Нет смысла совершать транзакции для чтения, и практически нет смысла использовать транзакцию для одного обновления (если только вы не хотите отменить это обновление позже), но если выПришлось собрать всю информацию о человеке и вставить ее в 17 различных таблиц. Вы можете использовать транзакцию, чтобы убедиться, что все работает или все не удалось, чтобы у вас не было частичных данных.Вам не нужно беспокоиться о снятии 9 из 17 вкладышей, если произошел сбой;вы просто откатываете транзакцию, и вставка так и не произошла, хотя числа автоинкрементов могут оставаться на одном

Существуют ли ограничения на количество данных, которые можно увеличить в транзакции?Технически да, но я думаю, что вряд ли вы нарушите их с корпоративной БД, если будете придерживаться следующего практического правила, которое ..

Реально, вы, вероятно, хотите, чтобы наборы транзакций были маленькимикак можно оставить кому-то минимальную головную боль, чтобы разобраться, когда это пойдет не так.Не сохраняйте каждого нового клиента, которого вы приобрели, на целый год в одной транзакции, а затем решите совершить транзакцию только потому, что это Рождество;десять тысяч вставок сорваны одним длинным именем или сбой сервера в канун Рождества не идеален

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...