Шаг 203.
Основы языка Python.
Доступ к базе данных SQLite из Python. Управление транзакциями

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

    Перед выполнением первого запроса автоматически запускается транзакция. Поэтому все запросы, изменяющие записи (INSERT, REPLACE, UPDATE и DELETE), необходимо завершать вызовом метода commit () объекта соединения. Если метод не вызвать и при этом закрыть соединение с базой данных, то все произведенные изменения будут отменены. Транзакция может автоматически завершаться при выполнении запросов CREATE TABLE, VACUUM и некоторых других. После выполнения этих запросов транзакция запускается снова.

    Если необходимо отменить изменения, следует вызвать метод rollback () объекта соединения. Для примера добавим нового пользователя, а затем отменим транзакцию и выведем содержимое таблицы:

>>> con = sqlite3.connect("catalog.db")
>>> cur = con.cursor ()
>>> cur.execute("INSERT INTO user VALUES (NULL, 'user@mail.ru', '')")
<sqlite3.Cursor object at 0x02426DA0>
>>> con.rollback () # Отмена изменений
>>> cur.execute ("SELECT * FROM user")
<sqlite3.Cursor object at 0x02426DA0>
>>> cur.fetchall ()
[(1, 'unicross@mail.ru', 'password1')]
>>> con.close ()

    Управлять транзакцией можно с помощью параметра isolation_level в функции connect (), а также с помощью атрибута isolation_level объекта соединения. Допустимые значения: DEFERRED, IMMEDIATE, EXCLUSIVE, пустая строка и None. Первые три значения передаются в инструкцию BEGIN. Если в качестве значения указать None, то транзакция запускаться не будет, - в этом случае нет необходимости вызывать метод commit (), поскольку все изменения будут сразу сохраняться в базе данных. Отключим автоматический запуск транзакции с помощью параметра isolation_level, добавим нового пользователя, а затем подключимся заново и выведем все записи из таблицы:

>>> con = sqlite3.connect ("catalog.db", isolation_level=None)
>>> cur = con.cursor ()
>>> cur.execute ("INSERT INTO user VALUES (NULL, 'user@mail.ru', '')")
<sqlite3.Cursor object at 0x026B0560>
>>> con.close()
>>> con = sqlite3.connect ("catalog.db")
>>> con.isolation_level = None # Отключение запуска транзакции
>>> cur = con.cursor ()
>>> cur.execute ("SELECT * FROM user")
<sqlite3.Cursor object at 0x02426DA0>
>>> cur.fetchall ()
[(1, 'unicross@mail.ru', 'password1'), (2, 'user@mail.ru', '')]
>>> con.close()

    Атрибут intransaction класса соединения возвращает True, если в данный момент существует активная транзакция, и False - в противном случае. Попытаемся добавить в таблицу нового пользователя и посмотрим, какие значения будет хранить этот атрибут в разные моменты времени:

>>> con = sqlite3.connect ("catalog.db")
>>> cur = con.cursor()
>>> cur.execute ("INSERT INTO user VALUES (NULL, 'user2@mail.ru', '')")
<sqlite3.Cursor object at 0x026B0560>
>>> con.in_transaction # Есть активная транзакция
True
>>> con.commit () # Завершаем транзакцию
>>> con.in_transaction # Нет активной транзакции
False
>>> cur.close ()
>>> con.close ()

    На следующем шаге мы рассмотрим создание пользовательской сортировки.




Предыдущий шаг Содержание Следующий шаг