PHP PHP  ·  25 вопросов  ·  ~70 мин  ·  ⏱ Таймер 10:00  ·  Средний  · 

Транзакции и согласованность

Успешный commit ещё не означает правильный бизнес-результат. Вопросы требуют выбрать границы транзакции, учитывать исключения, блокировки и повтор запроса после сбоя или сетевой неопределённости.

Отвечено: 0 из 25
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. Прослеживайте все изменяемые ресурсы и момент, после которого операцию нельзя бездумно повторить. Время — 70 минут.
Вопрос 1 из 25
Когда изменения транзакции фиксируются?
PHP
$pdo->beginTransaction();
$orders->create($order);
$pdo->commit();
Вопрос 2 из 25
Что объединять в одну транзакцию?
PHP
$pdo->beginTransaction();
$accounts->debit($from, 100);
$accounts->credit($to, 100);
$pdo->commit();
Вопрос 3 из 25
Что произойдёт без beginTransaction при обычном автокоммите?
PHP
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
Вопрос 4 из 25
Почему commit следует выполнять после всех проверок базы?
Вопрос 5 из 25
Что неверно в коде?
PHPPHP/SQL
$pdo->beginTransaction();
$repo->createOrder($order);
$mailer->sendConfirmation($order);
$pdo->commit();
Вопрос 6 из 25
Когда вызывать rollBack?
PHP
$pdo->beginTransaction();
try {
    reserveStock($pdo, $orderId);
    debitBalance($pdo, $userId, $amount);
    $pdo->commit();
} catch (Throwable $error) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    throw $error;
}
Вопрос 7 из 25
Откатит ли rollback отправленный HTTP-запрос платёжному сервису?
PHP
$pdo->beginTransaction();
$orders->markPaid($orderId);
$payments->charge($card, 1000);
$pdo->rollBack();
Вопрос 8 из 25
Почему важно повторно бросить исключение после rollback?
PHP
try {
    $transaction->run($operation);
} catch (Throwable $error) {
    $pdo->rollBack();
    throw $error;
}
Вопрос 9 из 25
Что делает finally в транзакционной обёртке?
Вопрос 10 из 25
Какой шаблон корректнее?
PHPPHP/SQL
$pdo->beginTransaction();
try { $work(); $pdo->commit(); }
catch(Throwable $e){ if($pdo->inTransaction())$pdo->rollBack(); throw $e; }
Вопрос 11 из 25
Что такое потерянное обновление?
PHP
$balanceA = 100;
$balanceB = 100;

$afterA = $balanceA - 30;
$afterB = $balanceB - 50;
Вопрос 12 из 25
Как атомарно уменьшить остаток, только если товара хватает?
PHP
$stmt = $pdo->prepare(
    'UPDATE stock SET amount = amount - :n WHERE id = :id AND amount >= :n'
);
$stmt->execute(['n' => $quantity, 'id' => $productId]);
if ($stmt->rowCount() !== 1) {
    throw new DomainException('Недостаточный остаток');
}
Вопрос 13 из 25
Что даёт SELECT ... FOR UPDATE?
Вопрос 14 из 25
Зачем выбирать уровень изоляции осознанно?
Вопрос 15 из 25
Что такое неповторяемое чтение?
Вопрос 16 из 25
Когда retry транзакции уместен?
PHP
for ($attempt = 1; $attempt <= 3; $attempt++) {
    try {
        $transaction->run($work);
        break;
    } catch (DeadlockException|SerializationFailure $error) {
        if ($attempt === 3) throw $error;
        usleep(random_int(10_000, 80_000));
    }
}
Вопрос 17 из 25
Почему весь блок должен быть идемпотентным для retry?
PHP
$transaction->run(function () use ($command): void {
    $orders->createOnce($command->operationId, $command->data);
    $outbox->addOnce($command->operationId, 'OrderCreated');
});
Вопрос 18 из 25
Что такое ключ идемпотентности?
Вопрос 19 из 25
Почему sleep без случайности при массовых retry вреден?
Вопрос 20 из 25
Какие ошибки нельзя просто повторять?
Вопрос 21 из 25
Почему один PDO в тесте не выявляет гонку?
PHP
$first = new PDO($dsn, $user, $password);
$second = new PDO($dsn, $user, $password);
$first->beginTransaction();
$second->beginTransaction();
Вопрос 22 из 25
Что проверять после искусственного сбоя между двумя UPDATE?
PHP
$pdo->beginTransaction();
$accounts->debit($from, 100);
throw new RuntimeException('Сбой между изменениями');
$accounts->credit($to, 100);
Вопрос 23 из 25
Как диагностировать deadlock?
Вопрос 24 из 25
Почему тест rollback должен заново читать данные отдельным запросом?
Вопрос 25 из 25
Какая метрика полезна в эксплуатации?

Ответьте на все 25 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу