Ответ
Уровень изоляции транзакций в JDBC задается с помощью метода Connection.setTransactionIsolation(int level). Этот метод необходимо вызывать до начала транзакции (перед setAutoCommit(false) или любой операцией, изменяющей данные).
Доступные уровни изоляции (константы интерфейса Connection):
TRANSACTION_READ_UNCOMMITTED— самое слабое. Допускает грязное чтение (Dirty Read), неповторяемое чтение (Non-repeatable Read) и фантомное чтение (Phantom Read).TRANSACTION_READ_COMMITTED— стандартный уровень для многих СУБД (например, PostgreSQL, Oracle). Предотвращает грязное чтение.TRANSACTION_REPEATABLE_READ— предотвращает грязное и неповторяемое чтение. Используется в MySQL по умолчанию (InnoDB).TRANSACTION_SERIALIZABLE— самое строгое. Полная изоляция, транзакции выполняются последовательно.TRANSACTION_NONE— транзакции не поддерживаются (редко используется).
Пример установки уровня READ_COMMITTED:
Connection conn = dataSource.getConnection();
// Установка уровня ДО начала транзакции
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conn.setAutoCommit(false);
// ... выполнение операций
conn.commit();
Важные замечания:
- Поддерживаемые уровни зависят от конкретной СУБД и драйвера JDBC. Не все уровни могут быть доступны.
- Уровень изоляции можно проверить с помощью
Connection.getTransactionIsolation(). - Повышение уровня изоляции увеличивает корректность данных, но снижает производительность из-за более строгого блокирования.
Ответ 18+ 🔞
Давай разберём эту тему про уровни изоляции, а то тут, блядь, такой пиздец творится, что волосы дыбом встают! Представь, два потока лезут в одну базу, как два алкаша в последнюю бутылку — без правил начнётся драка, данные порвут, всё просрут.
В JDBC, чтобы такого пиздопроёбища не случилось, есть штука под названием Connection.setTransactionIsolation(int level). Запомни раз и нахуй: вызывать этот метод надо до того, как ты начнёшь транзакцию! То есть перед setAutoCommit(false) или первой же операцией, которая данные трогает. Иначе будет как в том анекдоте: «после драки кулаками не машут».
Доступные уровни, они как круги ада — от лёгкого пиздеца до полного дзена, но за дзен надо платить скоростью.
Смотри, какие константы в интерфейсе Connection есть:
TRANSACTION_READ_UNCOMMITTED— это, ёпта, полный бардак. Один поток пишет, даже не закоммитившись, а второй уже это дерьмо читает. Грязное чтение (Dirty Read), неповторяемое, фантомы — всё в одном флаконе, как дешёвый самогон. Только для отчаянных, кому похуй на целостность.TRANSACTION_READ_COMMITTED— нормальный, адекватный уровень. Как в приличном обществе: пока не положил в карман (не закоммитил), никто твои деньги не видит. Грязное чтение отсекает. Его многие СУБД, типа PostgreSQL или Oracle, по умолчанию используют. Работает, не грузит сильно.TRANSACTION_REPEATABLE_READ— тут уже серьёзнее. Обещает, что если ты в транзакции дважды прочитал одну запись, то получишь одно и то же. То есть от соседней транзакции тебе не прилетит неожиданное изменение прямо под носом. В MySQL (InnoDB) это дефолт, между прочим.TRANSACTION_SERIALIZABLE— это, блядь, железный занавес. Полная изоляция, будто транзакции выполняются строго по очереди, одна за другой. Никаких фантомов, никаких сюрпризов. Но и производительность, ядрёна вошь, может накрыться медным тазом, потому что блокировок овердохуища.TRANSACTION_NONE— а это вообще пидарас шерстяной, транзакций нет. Редкая хуйня, лучше даже не смотреть в эту сторону.
Вот как это в коде выглядит, смотри:
Connection conn = dataSource.getConnection();
// Установка уровня ДО начала транзакции, блядь! Не проеби момент!
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conn.setAutoCommit(false);
// ... выполнение операций
conn.commit();
И главное, на что внимание обратить, а то подозрение ебать чувствую:
- Поддержка уровней — это на совести СУБД и драйвера. Может оказаться, что твоя база какой-то уровень просто игнорит, выпендривается.
- Текущий уровень можно спросить через
Connection.getTransactionIsolation()— проверить, не обманули ли тебя. - И помни золотое правило: чем строже изоляция, тем надёжнее, но и тем медленнее всё будет. Выбирай по обстановке, не гонись за
SERIALIZABLE, если можно обойтисьREAD_COMMITTED. Иначе получишь правильные, но охуенно медленные данные, и все пользователи разбегутся, блядь.