На этом шаге мы рассмотрим конструкции, используемые для управления транзакциями.
Перед выполнением первого запроса автоматически запускается транзакция. Поэтому все запросы, изменяющие записи (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 ()
На следующем шаге мы рассмотрим создание пользовательской сортировки.