💡 Инструкция: Выберите один ответ из пяти. Время — 70 минут. У каждого задания ровно один правильный вариант. Фрагменты рассчитаны на Ruby 4.0.6; задания Rails — на Rails 8.1.3. После завершения откроются общий процент, 5 тематических результатов и разбор всех ответов.
Вопрос 1 из 25
Разберите выражения по порядку. Как завершится фрагмент из раздела «Границы транзакции»? Выберите связку, в которой верны и основной вывод, и его обоснование.
Ruby Ruby — Границы транзакции Копировать
# Проследите выполнение и выберите точный результат.
ApplicationRecord.transaction do
debit.update!(balance: debit.balance - 10)
credit.update!(balance: credit.balance + 10)
end
Обе записи в одной транзакции фиксируются вместе либо откатываются при исключении `save!`. Это объясняется тем, что транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
Обе записи в одной транзакции фиксируются вместе либо откатываются при исключении `save!`. Это объясняется тем, что `lock`/`with_lock` используют блокировку строки до конца транзакции и позволяют сериализовать конкурентное изменение одной записи.
Обе записи в одной транзакции фиксируются вместе либо откатываются при исключении `save!`. Это объясняется тем, что тест транзакционной логики должен воспроизводить конкуренцию и реальную фиксацию; транзакционная обёртка самого теста может скрывать after_commit.
Уникальный ключ операции позволяет повторному запросу найти прежний перевод вместо создания второго. Это объясняется тем, что транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
CHECK не позволяет сохранить отрицательный баланс даже при update_all или прямом SQL. Это объясняется тем, что транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
Вопрос 6 из 25
Где в показанном решении «Границы транзакции» скрыт дефект, который проявится не на каждом входе? Проверьте обе половины ответа: частично верный вариант остаётся неверным.
Ruby Ruby — Границы транзакции Копировать
# Обычный запуск проходит. Найдите скрытый риск.
ApplicationRecord.transaction do
debit.update!(balance: debit.balance - 10)
credit.update!(balance: credit.balance + 10)
end
Слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации. Причина — транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
Внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится. Причина — инвариант должен быть выражен на самом низком надёжном уровне: ограничения базы защищают от всех путей записи, модель — только от путей через неё.
Внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится. Причина — `lock`/`with_lock` используют блокировку строки до конца транзакции и позволяют сериализовать конкурентное изменение одной записи.
Callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks. Причина — транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
Внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится. Причина — транзакция базы охватывает только операции того же соединения/базы; HTTP-вызов, письмо или другая база не откатываются вместе с ней.
Вопрос 8 из 25
Почему успешный пример ещё не доказывает надёжность решения «Повтор операции»? Верный вариант не содержит частично правильной подмены причины или следствия.
Ruby Ruby — Повтор операции Копировать
# Обычный запуск проходит. Найдите скрытый риск.
Transfer.transaction do
transfer = Transfer.find_or_initialize_by(request_id: request_id)
transfer.amount ||= amount
transfer.save!
end
# unique index on transfers.request_id
Callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks. Уязвимое место возникает потому, что повтор транзакции безопасен только при идемпотентных локальных и внешних действиях; исключение после commit может скрыть уже выполненную операцию.
Слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации. Уязвимое место возникает потому, что повтор транзакции безопасен только при идемпотентных локальных и внешних действиях; исключение после commit может скрыть уже выполненную операцию.
Слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации. Уязвимое место возникает потому, что тест транзакционной логики должен воспроизводить конкуренцию и реальную фиксацию; транзакционная обёртка самого теста может скрывать after_commit.
Слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации. Уязвимое место возникает потому, что инвариант должен быть выражен на самом низком надёжном уровне: ограничения базы защищают от всех путей записи, модель — только от путей через неё.
Внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится. Уязвимое место возникает потому, что повтор транзакции безопасен только при идемпотентных локальных и внешних действиях; исключение после commit может скрыть уже выполненную операцию.
Вопрос 16 из 25
Какое изменение устраняет причину проблемы в теме «Границы транзакции», а не маскирует симптом? Правильным считается только полностью согласованное утверждение.
Ruby Ruby — Границы транзакции Копировать
# Выберите изменение, которое исправляет причину.
ApplicationRecord.transaction do
debit.update!(balance: debit.balance - 10)
credit.update!(balance: credit.balance + 10)
end
Дублировать критичный инвариант ограничением базы и удобной прикладной валидацией, согласовав их формулировки. Так закрывается риск: внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится.
Держать транзакцию короткой, а внешний эффект координировать через outbox/saga и идемпотентную доставку. Так закрывается риск: внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится.
Держать транзакцию короткой, а внешний эффект координировать через outbox/saga и идемпотентную доставку. Так закрывается риск: callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks.
Блокировать минимальный набор строк в стабильном порядке и не выполнять внутри медленные внешние операции. Так закрывается риск: внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится.
Держать транзакцию короткой, а внешний эффект координировать через outbox/saga и идемпотентную доставку. Так закрывается риск: слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации.
Вопрос 19 из 25
Какое действие добавляет недостающую гарантию в блоке «Согласованность»? Смотрите на всю причинную связку, а не только на знакомую формулировку.
Ruby Ruby — Согласованность Копировать
# Выберите изменение, которое исправляет причину.
# Миграция PostgreSQL
add_check_constraint :accounts,
'balance >= 0',
name: 'accounts_balance_nonnegative'
# Модель может добавить понятное сообщение пользователю.
Держать транзакцию короткой, а внешний эффект координировать через outbox/saga и идемпотентную доставку. Решение адресует следующий дефект: callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks.
Блокировать минимальный набор строк в стабильном порядке и не выполнять внутри медленные внешние операции. Решение адресует следующий дефект: callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks.
Дублировать критичный инвариант ограничением базы и удобной прикладной валидацией, согласовав их формулировки. Решение адресует следующий дефект: внешний API, вызванный внутри транзакции, может успешно принять команду, а локальная база затем откатится.
Дублировать критичный инвариант ограничением базы и удобной прикладной валидацией, согласовав их формулировки. Решение адресует следующий дефект: callback-валидация проходит на снимке данных и может проиграть гонку; `update_all` к тому же обходит callbacks.
Дублировать критичный инвариант ограничением базы и удобной прикладной валидацией, согласовав их формулировки. Решение адресует следующий дефект: слепой retry всего блока с `create!` дублирует запись, если клиент не получил ответ после успешной фиксации.
Вопрос 25 из 25
Какой сценарий проверит не только результат, но и побочный эффект решения «Тестовый сценарий»? Выберите связку, в которой верны и основной вывод, и его обоснование.
Проверить существующие плохие данные перед включением ограничения, иначе миграция остановится в рабочей среде. На этой границе проверяется мера: создать детерминированный барьер между чтением и записью и проверять конечный инвариант, а не конкретный порядок потоков.
Проверить адаптер и уровень изоляции, используемые в рабочей базе: SQLite-тест не заменяет поведение PostgreSQL. На этой границе проверяется мера: блокировать минимальный набор строк в стабильном порядке и не выполнять внутри медленные внешние операции.
Проверить адаптер и уровень изоляции, используемые в рабочей базе: SQLite-тест не заменяет поведение PostgreSQL. На этой границе проверяется мера: дублировать критичный инвариант ограничением базы и удобной прикладной валидацией, согласовав их формулировки.
Проверить адаптер и уровень изоляции, используемые в рабочей базе: SQLite-тест не заменяет поведение PostgreSQL. На этой границе проверяется мера: создать детерминированный барьер между чтением и записью и проверять конечный инвариант, а не конкретный порядок потоков.
Проверить deadlock/timeout как ожидаемый временный исход и повторять всю транзакцию, а не только последнюю запись. На этой границе проверяется мера: создать детерминированный барьер между чтением и записью и проверять конечный инвариант, а не конкретный порядок потоков.