Как реализовать Pessimistic Locking
1️⃣ Как кратко ответить
Pessimistic Locking реализуется путем блокировки записи в базе данных на уровне транзакции, чтобы предотвратить одновременный доступ других транзакций. Это достигается использованием SQL-запросов с блокировками, таких как SELECT ... FOR UPDATE, которые блокируют выбранные строки до завершения транзакции.
2️⃣ Подробное объяснение темы
Pessimistic Locking — это стратегия управления конкурентным доступом к данным в базе данных, при которой запись блокируется для других транзакций, пока текущая транзакция не завершится. Это предотвращает проблемы, связанные с одновременным изменением данных, такие как "грязное" чтение, потеря обновлений и другие аномалии.
Зачем это нужно
Pessimistic Locking используется в системах, где высока вероятность конфликтов при одновременном доступе к одним и тем же данным. Это особенно важно в сценариях, где данные должны оставаться консистентными и точными, например, в банковских системах, системах управления запасами и других критически важных приложениях.
Как это работает
При использовании Pessimistic Locking транзакция, которая хочет изменить данные, сначала блокирует их, чтобы другие транзакции не могли их изменить до завершения текущей транзакции. Это достигается с помощью специальных SQL-запросов, которые устанавливают блокировки на уровне строк или таблиц.
Пример реализации
Рассмотрим пример использования Pessimistic Locking в Java с использованием JDBC и SQL-запроса SELECT ... FOR UPDATE.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PessimisticLockingExample {
public static void main(String[] args) {
String jdbcUrl = "jdbc:mysql://localhost:3306/mydatabase";
String username = "user";
String password = "password";
try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password)) {
// Устанавливаем автоматическое подтверждение транзакций в false
connection.setAutoCommit(false);
// Подготавливаем SQL-запрос с блокировкой
String sql = "SELECT balance FROM accounts WHERE account_id = ? FOR UPDATE";
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
preparedStatement.setInt(1, 1); // Указываем ID аккаунта, который хотим заблокировать
// Выполняем запрос
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
// Получаем текущий баланс
int balance = resultSet.getInt("balance");
System.out.println("Current balance: " + balance);
// Логика обновления баланса
int newBalance = balance - 100; // Например, снимаем 100 единиц
System.out.println("New balance: " + newBalance);
// Обновляем баланс в базе данных
String updateSql = "UPDATE accounts SET balance = ? WHERE account_id = ?";
try (PreparedStatement updateStatement = connection.prepareStatement(updateSql)) {
updateStatement.setInt(1, newBalance);
updateStatement.setInt(2, 1);
updateStatement.executeUpdate();
}
}
}
}
// Подтверждаем транзакцию
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Объяснение кода
-
Установка соединения с базой данных: Используем
DriverManager.getConnectionдля подключения к базе данных с указанными URL, именем пользователя и паролем. -
Отключение автоматического подтверждения транзакций:
connection.setAutoCommit(false);— это позволяет вручную управлять транзакциями, что необходимо для использования блокировок. -
Подготовка SQL-запроса с блокировкой:
SELECT balance FROM accounts WHERE account_id = ? FOR UPDATE— этот запрос блокирует строку с указаннымaccount_id, предотвращая доступ других транзакций до завершения текущей. -
Выполнение запроса и обработка результата: Извлекаем текущий баланс и выполняем необходимые операции (например, обновление баланса).
-
Обновление данных: Используем
UPDATEдля изменения данных в заблокированной строке. -
Подтверждение транзакции:
connection.commit();— фиксируем изменения в базе данных, снимая блокировку.
Pessimistic Locking гарантирует, что данные остаются консистентными, но может привести к снижению производительности из-за блокировок, особенно в системах с высокой конкуренцией.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться