Будет ли всегда запрещено параллельное чтение одной записи транзакциями из разных потоков?

«Будет ли всегда запрещено параллельное чтение одной записи транзакциями из разных потоков?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Почему это возможно:

  • В системах, использующих MVCC (Multi-Version Concurrency Control), каждый поток читает согласованный снимок данных на момент начала своей транзакции, что не мешает другим потокам делать то же самое.
  • При использовании оптимистичных блокировок чтение также не блокирует запись.

Когда чтение может быть заблокировано:

  1. При использовании пессимистичных блокировок на чтение, например:
    SELECT * FROM table WHERE id = 1 FOR SHARE; -- Блокировка на чтение в SQL
  2. При явном использовании примитивов синхронизации в коде:
    ReadWriteLock lock = new ReentrantReadWriteLock();
    lock.readLock().lock(); // Эта блокировка совместима с другими readLock()
    try {
        // чтение данных
    } finally {
        lock.readLock().unlock();
    }
  3. На самом строгом уровне изоляции SERIALIZABLE некоторые СУБД могут использовать блокировки диапазонов, которые потенциально могут затрагивать и операции чтения.

Вывод: По умолчанию параллельное чтение разрешено. Запрет возникает только при явном указании через механизмы блокировок или в специфических условиях изоляции транзакций.