Не позволяйте SELECT извлекать строки, зафиксированные после начала транзакции.

Учитывая этот сценарий:

TIME  TRANSACTION 1             TRANSACTION 2
1sec  BEGIN
2sec  INSERT RECORDS INTO T1   
3sec  (doing other things)      BEGIN
4sec  (doing other things)      (doing other things)   
5sec  COMMIT                    (doing other things)   
6sec                            SELECT * FROM T1    <<- GETS ROWS INSERTED BY T1

Согласно документам postgres:

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

Вопрос в том, как избежать SELECT фиксации строк между началом транзакции и началом запроса.


person Christian    schedule 09.04.2013    source источник


Ответы (2)


Описанная вами ситуация называется «фантомным чтением» и невозможна, если вы используете уровень изоляции, который предотвращает это, например REPEATABLE READ или SERIALIZABLE.

http://www.postgresql.org/docs/current/static/transaction-iso.html< /а>

Вы можете изменить уровень изоляции с помощью команды SET TRANSACTION:

http://www.postgresql.org/docs/current/static/sql-set-transaction.html

В зависимости от интерфейса, который вы используете для подключения к базе данных, вы также можете использовать соответствующие вызовы API (например, Connection.setTransactionIsolation() в Java/JDBC).

person a_horse_with_no_name    schedule 09.04.2013

Установите уровень изоляции транзакций на сериализуемый.

http://www.postgresql.org/docs/9.1/static/transaction-iso.html

person drquicksilver    schedule 09.04.2013