← Назад к вопросам

Что такое isolation level в Spring Data?

2.0 Middle🔥 141 комментариев
#Spring Boot и Spring Data

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Isolation Level в Spring Data

Isolation Level — это уровень изоляции транзакций, который определяет, как одновременные транзакции взаимодействуют друг с другом при работе с базой данных. Isolation level контролирует видимость изменений, сделанных одной транзакцией, для других транзакций и защищает от различных проблем параллельного доступа к данным.

Проблемы параллельного доступа

Перед рассмотрением уровней изоляции важно понимать проблемы, которые они решают:

Dirty Read — чтение незафиксированных (грязных) данных. Одна транзакция читает данные, которые другая транзакция изменила, но ещё не подтвердила.

Non-repeatable Read — неповторяющееся чтение. Одна транзакция читает одно и то же значение несколько раз, но между чтениями другая транзакция изменяет это значение.

Phantom Read — фантомное чтение. Одна транзакция выполняет запрос, получает набор строк, а затем другая транзакция добавляет новые строки, и при повторном запросе появляются новые данные.

Уровни изоляции транзакций

READ UNCOMMITTED — самый низкий уровень изоляции. Разрешает читать незафиксированные данные других транзакций:

  • Защита: нет
  • Возможны проблемы: Dirty Read, Non-repeatable Read, Phantom Read
  • Производительность: максимальная
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void processData() {
    // Код, который может прочитать грязные данные
}

READ COMMITTED — стандартный уровень изоляции. Разрешает читать только подтверждённые данные:

  • Защита: от Dirty Read
  • Возможны проблемы: Non-repeatable Read, Phantom Read
  • Производительность: хорошая
@Transactional(isolation = Isolation.READ_COMMITTED)
public void transferMoney(Long fromAccount, Long toAccount, BigDecimal amount) {
    Account from = accountRepository.findById(fromAccount).orElse(null);
    Account to = accountRepository.findById(toAccount).orElse(null);
    // Гарантирует чтение актуальных данных других транзакций
}

REPEATABLE READ — обеспечивает повторяющееся чтение одних и тех же данных:

  • Защита: от Dirty Read и Non-repeatable Read
  • Возможны проблемы: Phantom Read
  • Производительность: средняя
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void calculateBalance() {
    BigDecimal balance1 = accountRepository.getSumOfAllAccounts();
    // Даже если другая транзакция изменит значения, мы получим одинаковый результат
    BigDecimal balance2 = accountRepository.getSumOfAllAccounts();
}

SERIALIZABLE — самый высокий уровень изоляции. Обеспечивает полную изоляцию транзакций:

  • Защита: от всех проблем (Dirty Read, Non-repeatable Read, Phantom Read)
  • Возможны проблемы: нет
  • Производительность: минимальная
@Transactional(isolation = Isolation.SERIALIZABLE)
public void criticalOperation() {
    // Полная гарантия изоляции, но может быть очень медленным
}

Использование в Spring Data JPA

Декоратор @Transactional из org.springframework.transaction.annotation позволяет указывать уровень изоляции:

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Isolation;

@Service
public class OrderService {
    
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Order createOrder(OrderRequest request) {
        // Создание заказа
        Order order = new Order();
        order.setCustomerId(request.getCustomerId());
        order.setTotal(request.getTotal());
        return orderRepository.save(order);
    }
    
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public void updateInventory(Long productId, int quantity) {
        Product product = productRepository.findById(productId).orElseThrow();
        product.setStock(product.getStock() - quantity);
        productRepository.save(product);
    }
}

Таблица сравнения

УровеньDirty ReadNon-repeatable ReadPhantom ReadПроизводительность
READ_UNCOMMITTEDДаДаДаОчень высокая
READ_COMMITTEDНетДаДаВысокая
REPEATABLE_READНетНетДаСредняя
SERIALIZABLEНетНетНетНизкая

Выбор уровня изоляции

READ_UNCOMMITTED — почти никогда не используется в production из-за неконтролируемых проблем.

READ_COMMITTED — стандартный выбор для большинства приложений. Обеспечивает хороший баланс между безопасностью и производительностью. По умолчанию в PostgreSQL и SQL Server.

REPEATABLE_READ — используется для операций, требующих согласованности данных в рамках транзакции. По умолчанию в MySQL с InnoDB.

SERIALIZABLE — используется только для критически важных операций, где гарантия полной изоляции стоит дороговизны производительности.

Практический пример

@Service
public class BankService {
    
    @Autowired
    private AccountRepository accountRepository;
    
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void transferBetweenAccounts(Long fromId, Long toId, BigDecimal amount) {
        // SERIALIZABLE гарантирует, что никакие другие транзакции
        // не смогут изменить эти счета в процессе передачи
        Account from = accountRepository.findById(fromId).orElseThrow();
        Account to = accountRepository.findById(toId).orElseThrow();
        
        if (from.getBalance().compareTo(amount) < 0) {
            throw new InsufficientFundsException();
        }
        
        from.setBalance(from.getBalance().subtract(amount));
        to.setBalance(to.getBalance().add(amount));
        
        accountRepository.save(from);
        accountRepository.save(to);
    }
}

Выбор правильного уровня изоляции — ключевой момент оптимизации приложения, так как он напрямую влияет на безопасность данных и производительность системы.

Что такое isolation level в Spring Data? | PrepBro