Уровень изоляции Postgres для обновления нескольких разных строк в наборе - PullRequest
0 голосов
/ 31 октября 2018

Сначала я опишу сами данные и действия над ними. Документы, хранящиеся в базе данных, объединяются с сущностью «сеанс». Документы имеют знак сохранения IsSaved, указывая, что этот документ был сохранен.

Table Documents
{
    fileGuid uuid
    isSaved boolean
    sessionGuid uuid
}

FrontEnd обращается к методу api асинхронно, передавая каждый документ. Логика этого метода следующая:

  1. Документ сохранен в хранилище файлов
  2. Документ помечен как сохраненный и сохранен в базе данных.
  3. Запрос документов сессии выполнен.
  4. Когда все документы в сеансе сохранены (результат == true), запускается логика для дальнейшей обработки всего сеанса:
await _fileSaver.SaveFilesAsync (fileGuid, content);
var document = await _documentStorage.GetAsync (fileGuid);
await MarkSavedAsync (sessionFile);
var result = await CheckAllSavedAsync (sessionFile.SessionGuid);
if (result)
{
   ...... NextProcessing (sessionFile.sessionGuid)
}

В этом случае, поскольку веб-интерфейс вызывает метод параллельно для каждого файла, то в строке 5 мы можем получить значение «true» 2 раза, а затем логика NextProcessing дублируется

Я попытался обернуть сохранение и извлечь в транзакцию с уровнем изоляции Serializable:

await _fileSaver.SaveFilesAsync (fileGuid, content);
var document = await _documentStorage.GetAsync (fileGuid);

_context.Database.BeginTransaction (isolationLevel);
await MarkSavedAsync (sessionFile);
_context.SaveChanges ();
var result = await CheckAllSavedAsync (sessionFile.SessionGuid);
_context.Database.CommitTransaction ();
if (result)
{
   ...... NextProcessing (sessionFile.sessionGuid)
}

Но в этом случае логично, что иногда обе транзакции в строке 9 выбирают false. И NextProcessing никогда не вызывал. Как я могу обновить один файл набора и выбрать знак для остальных в изоляции?

пс. web-api публикуется на нескольких серверах. БД - postgres

...