Estou trabalhando com o PostgreSQL 9.3 usando a psycopg2
API do banco de dados.
Eu tenho a API do banco de dados definida no nível mínimo de isolamento (modo "autocommit") e estou gerenciando minhas próprias transações diretamente via SQL. Exemplo:
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;")
Basicamente, a transação iniciada pelo cur.execute("BEGIN;")
limita-se apenas a esse cursor ou é para toda a conexão ( self.conn.cursor()
)?
Algumas das coisas mais complexas que estou fazendo envolvem várias operações de banco de dados separadas, que logicamente divido em funções. Como tudo isso está em uma classe que tem a conexão como membro, é muito mais conveniente criar cursores dentro de cada função. No entanto, não tenho certeza de como funciona a criação de cursores em uma transação.
Basicamente, se as transações forem por conexão, posso criar muitos cursores instantaneamente dentro da transação. Se eles forem por cursor, isso significa que tenho que passar o cursor por todos os lugares. Qual é?
A documentação não aborda isso, embora o fato de você poder ligar connection.commit()
me deixe bastante confiante de que o controle da transação é por conexão.
As transações são por sessão, ou seja, por conexão.
O PostgreSQL não oferece suporte à suspensão e retomada de transações, portanto, psycopg2 não poderia criá-las por cursor, a menos que criasse implicitamente novas conexões nos bastidores.
Na prática, não acho os cursores do psycopg2 particularmente úteis. Eles podem reter conjuntos de resultados se você não estiver usando a busca incremental do servidor, mas não os acho bons para muito mais.
Por que emitir manualmente
begin
ecommit
embora, em vez de usar os métodos de conexão para eles?Da documentação do psycopg2 :
Ao mesmo tempo, a partir da versão 2.4.2, existe o
autocommit
atributo (grifo nosso):