Учитывая систему, которая обеспечивает:
- Оптимистическое управление параллелизмом / управление версиями для каждого объекта (используя CAS - Check-and-Set)
- Транзакции, которые никогда не должны охватывать более одного объекта.
- Снимок изоляции
Эта система считается сериализуемой ?
Из изоляции моментального снимка
В аномалии асимметрии при записи две транзакции (T1 и T2) одновременно читают перекрывающийся набор данных (например, значения V1 и V2), одновременно выполняют непересекающиеся обновления (например, обновления T1 V1, обновления T2 V2) и, наконец, одновременно фиксируют, ни одна из них не видела обновление, выполненное другим. Если бы система была сериализуемой, такая аномалия была бы невозможна, так как T1 или T2 должны были бы появиться «первыми» и быть видимыми для других. Напротив, изоляция моментальных снимков позволяет записывать перекос аномалий.
В качестве конкретного примера представьте, что V1 и V2 - это два баланса, которые держит один человек, Фил. Банк позволит V1 или V2 иметь дефицит при условии, что общая сумма в обоих случаях никогда не бывает отрицательной (т. Е. V1 + V2 ≥ 0). Оба баланса в настоящее время составляют 100 долларов. Фил инициирует две транзакции одновременно, T1 снимает 200 долларов с V1 и T2 снимает 200 долларов с V2.
Исходя из этого, представляется, что наличие возможности перекоса записи является единственной причиной, по которой система, гарантирующая изоляцию моментальных снимков, не сериализуема.
Однако в системе, которая не позволяет транзакции охватывать несколько объектов (в приведенных выше примерах V1 и V2), кажется невозможным возникновение перекоса записи .
Следовательно, описанная выше система является сериализуемой. Это верно?
источник
Ответы:
Нет, я не думаю, что ваши условия приводят к созданию системы, которую мы должны считать сериализуемой.
Изоляция моментальных снимков - это метод, который гарантирует, что транзакция видит один и тот же набор данных на протяжении всей транзакции. Изоляция моментальных снимков предоставляет некоторые гарантии, но не определяет все характеристики, необходимые для понимания того, как на самом деле работают транзакции (если мы не решим объединить изоляцию моментальных снимков и MVCC).
Изоляция моментальных снимков чаще всего реализуется с использованием MVCC, Multi Version Consistency Control. MVCC определяет более подробную информацию о транзакциях в контексте их снимков: это говорит о том, что они требуют изоляции только при конфликте записи (только местоположения или местоположения + значения, в зависимости от реализации). MVCC предоставляет расслабленную модель согласованности и страдает от асимметрии записи.
Модели расслабленной согласованности трудно понять, потому что они похожи на гибрид между отсутствием изоляции и полной изоляцией.
Итак, давайте сначала начнем со строгой модели параллелизма. Две транзакции должны быть изолированы друг от друга, если одна пишет в какие-либо данные, которые другая либо читает, либо записывает (и наоборот ...).
Когда мы не знаем, почему транзакция читает данные, мы должны предположить, что другое считанное значение может изменить поведение соответствующего клиента, поэтому условие перекрывающихся транзакций указывает на изоляцию. Без изоляции чтение устаревших данных в моментальном снимке может легко показать ослабленную согласованность, другой термин для которой - несогласованность, то есть ошибка.
Нам нужно только учитывать точные данные, прочитанные или записанные транзакциями, любые данные за пределами этого набора не должны рассматриваться. Однако важно понимать, что когда мы говорим о данных, считываемых транзакцией, мы обязательно должны включать в себя любые и все «метаданные» (а также данные и метаданные, считываемые метаоперациями, такими как проверка ограничений). Примерами метаданных являются / мета-операции: идентификация уникального нового первичного ключа; другая сумма всех столбцов; другой - что-то искать, а не находить; диапазон поиска или суммы. Это относится к комментарию @ Matthew о предотвращении дублирования, а также к ответу @Tersosauros, в котором он рассматривает состояние.
Например, это означает, что две транзакции перекрываются (требуется изоляция), когда они обе вставляют строку (при условии ограничения уникального первичного ключа), поскольку проверка ограничения ключа является синонимом чтения всего столбца первичного ключа. В качестве другого примера, поиск чего-либо и его обнаружение подобны чтению этого значения, а не обнаружение его - как просмотр каждого значения в столбце.
MVCC защищает только от перекрывающихся или конфликтующих записей, но не защищает от чтения (если также не записано этой транзакцией). Таким образом, чтобы получить ошибку согласованности в MVCC, все, что нам нужно сделать, это прочитать что-то, что было изменено другой транзакцией (где другая транзакция происходит после того, как получен снимок первого, но фиксируется первым), в то время как другая транзакция продолжает использовать устаревшие данные и принимает любое решение по-разному, основываясь на этих устаревших данных, по сравнению с тем, что он делал бы в соответствии с современными данными. Это легче вызвать, чем вы думаете.
Расслабленная согласованность - это еще один способ сказать потенциально непоследовательным или подверженным ошибкам. (Непринужденную согласованность не следует путать с возможной согласованностью, которая является другой популярной формой, подверженной ошибкам, чем «NoSQL».)
На ваш вопрос, когда вы говорите, что транзакции никогда не должны охватывать более одного объекта, это должно относиться как к чтению и записи, так и к метаданным (и метаоперациям), включая проверку непротиворечивости, совокупности столбцов, проверки отсутствия, поиск по диапазону и т. Д. р .: если так, то пока все хорошо.
Тем не мение...
Я понял из вашего вопроса, что вы используете изоляцию моментальных снимков (MVCC) для отдельных объектов (скажем, вместо блокировки объектов). (Вы также упоминаете CAS; я слышал о сравнении и обмене, о тестировании и установке, но не о проверке и установке, хотя я предполагаю, что это похоже).
Ваш вопрос написания подсказывает мне, что «объекты» имеют более чем одно поле, в противном случае условия вопроса были бы ненужными.
Следовательно, поскольку у ваших объектов, снятых с помощью snapshott / MVCC, есть более одного поля, вы склонны к перекосу в отдельных объектах. Если две транзакции обновляют один и тот же объект одновременно, можно прочитать поле значения объекта, сделанное устаревшим в результате одновременной другой транзакции на том же объекте, и продолжить, не зная, таким образом, потенциальной несогласованности (иначе ошибка).
Вместо этого вы можете использовать объектную блокировку, которая помешает двум транзакциям (для обновления) даже смотреть на один и тот же объект, если другая транзакция уже находилась в процессе.
Я считаю, что альтернативная форма изоляции моментальных снимков может быть реализована без использования сравнительной модели MVCC, основанной только на нарушении записи. Таким образом, вы можете (алгоритмически) повысить набор сравнения только для записи, чтобы включить также набор для чтения. Тогда две транзакции, обновляющие один и тот же объект, не смогут вызвать перекос записи (потому что попытка фиксации будет прервана позже). Я думаю, что это может быть подходящим решением проблемы, которую вы описываете, потому что вы уже получаете большую часть выгоды, которую MVCC купит для нас, исключая многоцелевые транзакции.
(Нам нужно только учитывать точные и конкретные элементы / поля для чтения или записи, но мы должны включать те, которые читаются как метаданные, потенциально во время мета-операций, чтобы предотвратить перекос записи (т. Е. Ошибку). Если мы удалим либо набор чтения из набора сравнения или мы не учитываем метаданные (потенциально используемые метаоперациями), тогда у нас есть модель, которая допускает ошибки.)
источник
Я думаю, что, как заявил @ pjc50 , ( подчеркивание добавлено :) « если транзакции ограничены чтением / записью одного объекта», тогда «ответ - да». Тем не менее, я думаю, где это падает в идее одного объекта.
В примере, взятом из изоляции моментального снимка , T1 и T2 не имеют общего значения. Тем не менее, они все еще потенциал для перекоса записи , потому что « ни [есть] видел обновление выполняется другой » источник . Поэтому именно способность транзакции видеть все другие обновления перед фиксацией делает транзакцию действительно сериализуемой.
Из сериализуемости :
К сожалению, из-за этого (и, как указывает @Matthew Марк Миллер ), мы также должны учитывать состояние и значения. С учетом этого две транзакции, использующие OCC , потенциально могут иметь перекос записи при записи любого состояния базы данных .
источник