• Вопросы по статьям на хабре и википедии про уровни изоляции транзаций - почему так написано?

    @footballer Автор вопроса
    Современные промышленные СУБД такой трюк провести не дадут (строки на время update будут заблокированы)

    строки будут заблокированы, даже если я явно не оберну update в транзакцию (потому что сработает автотранзакция)? Вот про это я и спрашивал, раз СУБД (ms sql) не дадут провести этот трюк, то для чего в той же ms sql нужен уровень изоляции READ UNCOMMITED ? Раз даже без выставления READ UNCOMMITED в явной транзакции все-равно этот трюк не пройдет. Раз в принципе невозможно потерянное обновление, то какой может быть смысл открывать транзакцию с READ UNCOMMITED ? Я выше предположил, что это может быть нужно, только если мне нужно несколько операций объединить в 1 атомарную единицу, т.е. будет не 1 апдейт, а несколько, и при этом мне нужно грязное чтение, тогда я буду вынужден открыть явную транзакцию с уровнем READ UNCOMMITED. Я угадал? Или не так?
  • Вопросы по статьям на хабре и википедии про уровни изоляции транзаций - почему так написано?

    @footballer Автор вопроса
    terrier:
    Однако, в системах, удовлетворяющих стандарту ANSI/ISO SQL такая ситуация запрещена, то есть хотя какая-нибудь изоляция есть всегда

    если говорить про ms sql , то хоть "какая-нибудь изоляция есть всегда" - это имеется ввиду, что даже одиночные запросы оборачиваются в автотранзакции, поэтому этот сценарий потери апдейта в ms sql - чисто теоретический?
    Если так, то для чего тогда в ms sql есть уровень изоляции транзакций READ UNCOMMITTED? Т.е когда я перед запросом могу написать:
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    и дальше в транзакции выполнить апдейт.
    Для чего устанавливать уровень изоляции READ UNCOMMITTED , если получается, что итак этот сценарий потери апдейта невозможен благодаря автотранзакциям?

    Хотя, сейчас появилась мысль: это может быть нужно, когда нужно несколько запросов обернуть в атомарную единицу, но при этом я почему-то хочу, чтобы при выполнении моих запросов существовало «грязное» чтение ? Тогда я вынужден обернуть запросы в транзакцию (для атомарности), но вынужден установить уровень READ UNCOMMITTED для существования грязного чтения. Это единственный вариант, который я нашел, для чего может быть нужен READ UNCOMMITTED. Я угадал?
  • Вопросы по статьям на хабре и википедии про уровни изоляции транзаций - почему так написано?

    @footballer Автор вопроса
    terrier:
    На счет статьи на хабре понял, я каким-то образом не заметил, что там во временную переменную сохраняется.
    Но все-равно не понятно это:
    Интерпретация №1 практически невозможен даже при уровне изоляции READ UNCOMMITED ( см. табличку внизу в вики или под спойлер в статье на хабре ).

    Я понимаю, что он невозможен при уровне изоляции READ UNCOMMITED. Вопрос был в том, что тогда когда он возможен? Когда транзакции вообще нет? Но ведь при отсутствии явной транзакции любые одиночные запросы неявно оборачиваются в автотранзакции, так? Т.е. даже если я выполняю параллельно 2 апдейта, не обернутые явно в транзакции и изменяющие одно и то же поле, то "потерянное обновление" все-равно невозможно, разве не так? а раз оно никогда не возможно, тогда зачем нужно создавать явно транзакцию с уровнем изоляции READ UNCOMMITED?
  • Вопросы по статьям на хабре и википедии про уровни изоляции транзаций - почему так написано?

    @footballer Автор вопроса
    Нет, я спрашивал именно про "уровни изоляции". Разъяснение по первому вопросу: если считать, что в ms sql существуют автотранзакции, а минимальный уровень изоляции транзакций = read uncommitted, то даже если у автотранзакций стоит минимальный уровень изоляции, то любые одиночные запросы (которые по умолчанию оборачиваются в автотранзакции) уже будут гарантировать отсутствие "потерянного обновления". Либо, если я ничего не понимаю, то объясните, плз, чтобы стало понятно.

    Разъяснение по второму вопросу: на хабре 2 апдейта одновременно меняют одно и то же поля и оба запроса внутри транзакций. Опять таки, учитывая, что минимальный уровень изоляции транзакции гарантирует отсутствие "потерянного обновления", то откуда у него оно появляется? Вот у него результат:
    Результат: Value = 6 Value = 8
    но с транзакциями явно должно быть
    Результат: Value = 6 Value = 13
  • Есть ли недостатки у транзакций?

    @footballer
    Непосредственно от внедрения транзакций ничего медленнее работать не начинает.

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

    что значит "сохранения на диск"? сохранение логов на диск? А они что, не всегда сразу же сохраняются на диск? Т.е. логи какое-то время пишутся только в оперативную память и только изредка записываются в постоянную память? А как же тогда целостность и консистентность данных, которые были изменены транзакциями, ведь при обрыве электричества тогда и логи из оперативной памяти сотрутся и будет невозможно откатить транзакции? Тогда смысл при таком сценарии вообще использовать транзакции?
  • Вопросы по статье на хабре о LINQ - IEnumerable и IQueryable, в чем разница?

    @footballer Автор вопроса
    А второй вопрос: почему вызов сишарпового метода из экспрешшена норм сработал в линкпаде, но кидает эксепшен при вызове из студии? Такое возможно вообще? Или только вариант, что я где-то накосячил в коде в линкпаде, раз у меня линкпад не упал?

    И еще. У юзера есть организация, у организации есть юзеры. Юзаем такой код:
    _dbContext.Organizations.Where(o => o.Name.Contains("Roga") && o.Users.Any(u => u.FirstName == "Petr")).Select(...)
    в организациях ищем только те организации, у которых имя содержит "Roga" и в юзерах есть хотя бы 1 Петр.
    Тут у нас две лямбды: внешняя, которая Expression, потому что передается в Where, который вызывается у DbSet, который реализует IQueryable. И внутренняя, которая Func , потому что вызывается у ICollection, она не Expression, потому что ICollection не реализует IQueryable.
    Т.к. первая лямбда - Expression, то query provider (или что там парсит запрос) сможет его распарсить и получить инфу обо всех "узлах", которые заюзаны в выражении: о полях объекта(o.Name, o.Users) , о переменных ("Roga"), об операторах (в данном случае &&) и о методах, которые вызываются на полях(методы Any и Contains, и дальше парсер, зная, что вызываются Any и Contains, уже поймет, в какие sql-команды преобразовать эти методы). Это как я понимаю происходящее при использовании Expression.
    Но тут меня напрягает то, что мы в метод Any передаем вложенную лямбду, которая не является экспрешшеном. Ведь парсер должен получить изнутри вложенной лямбды инфу о том, что "у Юзера нам нужно взять поле FirstName и сравнить его с "Petr"). Но вложенная лямбда не является экспрешшеном, т.е., распарсить ее не получится? Или несмотря на то, что вложенная лямбда - не Expression, а Func, но за счет того, что она внутри экспрешшена, сишарп все-равно ее передаст как Expression и она сможет быть распарсена?
    Я провел тест, который показал, что запрос в БД содержал фильтрацию по юзернейму "Petr", вот такой был запрос:
    FROM [dbo].[Organizations] AS [Extent1]
    WHERE ([Extent1].[Name] LIKE N'%Roga%') AND ( EXISTS (SELECT
    1 AS [C1]
    FROM [dbo].[AspNetUsers] AS [Extent3]
    WHERE ([Extent1].[Id] = [Extent3].[OrganizationId]) AND (N'Petr' = [Extent3].[FirstName])
    ))
    что говорит о том, что лямбда-Func была распарсена движком подобно лямбде-экспрешшену. За счет чего это произошло?
    Я, вообще, раньше считал, что тут вложенная лямбда распарсится (каким бы то ни было образом), что, собсвенно, и произошло. Но вот я только что захотел вынести вложенную функцию в отдельную переменную, чтобы заюзать ее дальше в Select. Т.е., я хотел сделать так:
    Func func = u => u.FirstName == "Petr";
    return _dbContext.Organizations.Where(o => o.Name.Contains("Roga") && o.Users.Any(func)).Select(...)
    и тут я подумал, если я так сделаю, то это уже будет конкретный вызов сишарповой переменной func изнутри экспрешшена, а это явно должно привести к падению. Я проверил этот код, и он реально кинул эксепшен
    *Internal .NET Framework Data Provider error 1025.*

    В общем, мои вопросы:
    1)любая вложенная в Expression лямбда тоже является экспрешшеном, несмотря на то, что ее тип может быть показан студией, как Func?
    2)если да, поэтому мы не можем ее вынести в отдельную переменную, чтобы заюзать в нескольких местах, потому что тогда мы во внешнем экспрешшене используем не лямбду, а ссылку на переменную с лямбдой?
    3)как-нибудь можно решить проблему невозможности вынесения вложенной лямбды в отдельную переменную? Объявить переменную как Expression не получается, т.к. Any на ICollection не принимает Expression.