Ответ
Транзакция — это атомарная и изолированная последовательность операций с базой данных, которая либо выполняется полностью (commit), либо полностью откатывается (rollback). Для тестирования понимание транзакций критично при проверке целостности данных и конкурентных сценариев.
Базовый пример SQL-транзакции:
BEGIN TRANSACTION; -- Начало транзакции
UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 123; -- Списание
UPDATE accounts SET balance = balance + 100.00 WHERE user_id = 456; -- Зачисление
-- Если оба UPDATE прошли успешно:
COMMIT; -- Фиксация изменений в БД
-- Если на любом этапе произошла ошибка (например, недостаточно средств):
-- ROLLBACK; -- Откат всех изменений в рамках этой транзакции
Свойства ACID и их влияние на тестирование:
-
Атомарность (Atomicity): "Все или ничего".
- Что тестировать: Сценарии сбоя (отключение сети, падение сервера) в середине транзакции. Убедиться, что данные не остаются в частично измененном состоянии.
-
Согласованность (Consistency): Транзакция переводит БД из одного валидного состояния в другое.
- Что тестировать: Соблюдение бизнес-правил (CHECK-ограничения, внешние ключи). Например, нельзя перевести сумму, превышающую баланс.
-
Изолированность (Isolation): Параллельные транзакции не должны влиять друг на друга.
- Что тестировать: Конкурентный доступ. Классические проблемы:
- "Грязное" чтение (Dirty Read): Чтение незакоммиченных данных другой транзакции. Тест: запустить две транзакции параллельно и проверить, видит ли вторая незавершенные изменения первой.
- Неповторяющееся чтение (Non-repeatable Read): Повторное чтение одних и тех же данных в рамках одной транзакции дает разные результаты. Тест: прочитать строку, затем после ее изменения другой транзакцией, прочитать снова.
- Что тестировать: Конкурентный доступ. Классические проблемы:
-
Долговечность (Durability): После commit изменения сохраняются даже при сбое системы.
- Что тестировать: Восстановление БД после сбоя. Убедиться, что закоммиченные перед падением данные не потеряны.
Практика для QA: При написании интеграционных или E2E-тестов часто необходимо очищать БД между тестами. Это удобно делать, оборачивая каждый тест в транзакцию, которая в конце откатывается:
// Пример на Java с Spring и JUnit 5
@SpringBootTest
@Transactional // Каждый тест выполняется в транзакции, которая откатывается после его завершения
class UserServiceIntegrationTest {
@Test
void createUser_ShouldPersistInDatabase() {
User user = new User("alice");
userRepository.save(user);
assertThat(userRepository.findById(user.getId())).isPresent();
// После завершения теста все изменения (сохранение пользователя) будут откачены.
// Следующий тест начнется с чистой БД.
}
} Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶