Чи проводяться транзакції в PostgreSQL через курсор `psycopg2` або за з'єднання?


10

Я працюю з PostgreSQL 9.3 за допомогою psycopg2API бази даних.

У мене встановлений API DB в мінімальному рівні ізоляції (режим "автокомісія") і я керую своїми транзакціями безпосередньо через SQL. Приклад:

cur = self.conn.cursor()
cur.execute("BEGIN;")
cur.execute("SELECT dbId, downloadPath, fileName, tags FROM {tableName} WHERE dlState=%s".format(tableName=self.tableName), (2, ))
ret = cur.fetchall()
cur.execute("COMMIT;")

По суті, чи є транзакція, яку розпочинає cur.execute("BEGIN;")лише цей курсор, чи це для всього з'єднання ( self.conn.cursor())?

Деякі з більш складних речей, які я роблю, стосуються декількох окремих операцій з базою даних, які я логічно розбиваю на функції. Оскільки це все в класі, який має з'єднання як член, набагато зручніше створювати курсори в межах кожної функції. Однак я не впевнений, як працює створення курсорів в рамках транзакції.

В основному, якщо транзакції здійснюються за з'єднання, я можу просто створити безліч курсорів під час руху в межах транзакції. Якщо вони за курсором, це означає, що я маю передавати курсор скрізь. Що це таке?

Документація цього не стосується, хоча той факт, що ви можете зателефонувати, connection.commit()робить мене досить впевненим, що контроль за транзакціями здійснюється за з'єднання.

Відповіді:


7

Операції проводяться за сеанс, тобто за з'єднання.

PostgreSQL не підтримує призупинення та відновлення транзакцій, тому psycopg2 не міг зробити їх курсором, якщо це неявно не створило нові зв’язки за кадром.

На практиці я не вважаю курсори psycopg2 особливо корисними. Вони можуть зберігати набори результатів, якщо ви не використовуєте інкрементальний доступ із сервера, але я не вважаю їх корисними для багатьох інших.

Навіщо вручну видавати beginі commitхоча, а не використовувати для них методи підключення?


Згідно з документацією, вся модель "DB API" насправді взагалі не підтримує явних транзакцій.
Підроблене ім’я

1
@FakeName Явно не потрібно begin. Якщо трансакція не відкрита, для вас запускається нова. Вам просто commitрозмежувати транзакції. Так що так, модель DB-API робить підтримку явні транзакції.
Крейг Рінгер

1
Якщо api БД робить це автоматично, без мого конкретного вказівки на це, це починається неявно . Крім того, це не має значення, оскільки (як я вже говорив у запитанні), я використовую режим автокомісії, тому що я не хочу цих автоматичних BEGINзаяв. Я не хочу psycopg2створювати нову транзакцію для кожної SELECT.
Підроблене ім’я

TL; DR в основному я хочу знати точний обсяг усіх транзакцій, що відбуваються, тому що А. Я божевільний таким чином, і Б. це дуже допомагає при налагодженні.
Підроблене ім’я

1
Я не був би здивований, побачивши з цим незвичайні помилки. Автокомісія AFAIK насправді призначена для автокомісії, а не керування транзакціями вручну. Якщо ви дійсно хочете вручну керувати сферами транзакцій, додатковий BEGINнешкідливий і просто ігнорується PostgreSQL з WARNING: there is already a transaction in progress.
Крейг Рінгер

1

З документації на psycopg2 :

У Psycopg транзакції обробляються класом з'єднання. За замовчуванням при першому надсиланні команди в базу даних (за допомогою одного з курсорів, створених підключенням), створюється нова транзакція. Наступні команди бази даних виконуватимуться в контексті однієї транзакції - не тільки команди, видані першим курсором, але й ті, які видаються всіма курсорами, створеними одним і тим же з'єднанням. Якщо якась команда не вдасться, транзакція буде перервана, і подальша команда не буде виконуватися до виклику методу rollback ().

У той же час, у версії 2.4.2 є autocommitатрибут (додано наголос):

Атрибут читання / запису: якщо Trueдрайвер не обробляє жодну транзакцію, і кожне повідомлення, що надсилається до бекенда, має негайний ефект; якщо False нова операція запускається при першому виконанні команди : методи commit()або rollback()повинні бути вручну викликані для припинення транзакції.

Режим автокомісії корисний для виконання команд, які потребують виконання поза транзакцією, наприклад, CREATE DATABASEабо VACUUM.

За замовчуванням є False(вручну ввести) відповідно до специфікації DBAPI.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.