python - connection.commit() 和cursor.execute ('commit' 之间有什么区别?

标签 python oracle

我想知道从性能角度来看哪个是更好的选择,即插入行后我们应该使用 connection.commit() 还是 cursor.execute('commit')考虑到我使用的是 Oracle 数据库。

最佳答案

根据文档,唯一明显的区别是两者属于不同的对象

Connection.commit() Commit any pending transactions to the database.

Cursor.execute() Execute a statement against the database

  1. 如果同一连接有多个游标,connection.commit() 将提交属于程序中任何游标的任何待处理事务。
  2. cursor.execute('commit') 您可能会认为只有属于相应游标的挂起事务才会被提交。这是一种误解,因为一旦您提交了相应连接中的任何游标,所有剩余的游标也将被提交。

我刚才解释的演示:

演示表

SQL> desc test_cursors
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 D                                                  DATE
 ID                                                 VARCHAR2(100)

简单的python程序

import cx_Oracle

host="ODCGRC1R.SCGER.DEV.CORP"
port=60995
sid='odcgrc1r'
user='CPL_REP'
password='Cpl3_r3p'
sid = cx_Oracle.makedsn(host, port, service_name=sid)

sql = ('insert into test_cursors values(sysdate,1)')

connection = cx_Oracle.connect(user, password, sid, encoding="UTF-8")
cursor = connection.cursor()
cursor.execute(sql)
connection.commit()

我们执行它只是插入一条记录,无论我们使用什么方法结果都是一样的。

C:\python>python testconn.py

C:\python>sqlplus cpl_rep/Cpl3_r3p@//ODCGRC1R.SCGER.DEV.CORP:60995/odcgrc1r

SQL*Plus: Release 12.2.0.1.0 Production on Sun Oct 3 11:54:18 2021

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Last Successful login time: Sun Oct 03 2021 11:54:14 +02:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> select * from test_cursors ;

D
---------
ID
--------------------------------------------------------------------------------
03-OCT-21
1

到目前为止,一切都很好。我们的记录已通过连接方法 commit 提交到表中(通过 cursor.execute('commit') 效果相同。现在,让我们将它与具有相同游标的多个语句一起使用

import cx_Oracle

host="ODCGRC1R.SCGER.DEV.CORP"
port=60995
sid='odcgrc1r'
user='CPL_REP'
password='Cpl3_r3p'
sid = cx_Oracle.makedsn(host, port, service_name=sid)

sql1 = ('insert into test_cursors values(sysdate,2)')
sql2 = ('insert into test_cursors values(sysdate,3)')

connection = cx_Oracle.connect(user, password, sid, encoding="UTF-8")
cursor = connection.cursor()
cursor.execute(sql1)
cursor.execute(sql2)
connection.commit()

让我们运行它并确认所有记录均已插入。

C:\python>python testconn.py

C:\python>sqlplus cpl_rep/Cpl3_r3p@//ODCGRC1R.SCGER.DEV.CORP:60995/odcgrc1r

SQL*Plus: Release 12.2.0.1.0 Production on Sun Oct 3 11:56:49 2021

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Last Successful login time: Sun Oct 03 2021 11:56:44 +02:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL>  select * from test_cursors ;

D                  ID
-------------------------------------------------------------------
03-OCT-21          1

03-OCT-21          2

03-OCT-21          3

嗯,正如预测的那样,connection.commit() 方法已经完成了它的工作,提交了连接中所有挂起的事务。

现在,让我们切换到cursor.execute('commit')。在下一个示例中,我有意从同一连接创建两个不同的游标,但我只会提交其中一个。我将 autocommit 设置为 false

import cx_Oracle

host="ODCGRC1R.SCGER.DEV.CORP"
port=60995
sid='odcgrc1r'
user='CPL_REP'
password='Cpl3_r3p'
sid = cx_Oracle.makedsn(host, port, service_name=sid)

sql1 = ('insert into test_cursors values(sysdate,4)')
sql2 = ('insert into test_cursors values(sysdate,5)')

connection = cx_Oracle.connect(user, password, sid, encoding="UTF-8")
connection.autocommit = False
cursor1 = connection.cursor()
cursor2 = connection.cursor()
cursor1.execute(sql1)
cursor2.execute(sql2)
cursor1.execute('commit')

我们执行它

C:\python>python testconn.py

C:\python>sqlplus cpl_rep/Cpl3_r3p@//ODCGRC1R.SCGER.DEV.CORP:60995/odcgrc1r

SQL*Plus: Release 12.2.0.1.0 Production on Sun Oct 3 12:06:13 2021

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Last Successful login time: Sun Oct 03 2021 12:06:11 +02:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> set lines 80
SQL> col id for a20
SQL> select * from test_cursors ;

D         ID
--------- --------------------
03-OCT-21 1
03-OCT-21 2
03-OCT-21 3
03-OCT-21 4
03-OCT-21 5

好吧,尽管游标2没有在程序中提交,但它确实在数据库中提交了。为什么 ?因为它们都属于同一个 connection.cursor() ,因此当我提交一个时,我确实提交了所有它们。

回到你的问题的目的,我相信它们在数据库中发生的事情方面是相同的。通常来说,我会使用connection.commit()来关闭与任意数量的不同事务的连接。但是,出于性能原因,如果您正在处理大型事务,最好在此过程中提交一些工作,例如避免撤消问题。但同样,这完全取决于您的代码正在做什么。

关于python - connection.commit() 和cursor.execute ('commit' 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69418919/

相关文章:

python - numpy - 获取随机整数作为 float

java - 如何解决 Oracle 客户端安装问题?

sql - 在 Oracle 中创建前导零

javascript - 通过 Node.js 运行子查询时 Oracle SQL 命令未正确结束

oracle - APEX_WEB_SERVICE.MAKE_REST_REQUEST 结果为 ORA-29248 : an unrecognized WRL was used to open a wallet

python - 通过 boto3 : ImproperlyConfigured 使用 Amazon S3 的 Django

python - 在 Python 中创建一个空的 Popen() 对象?

python 查找函数的类型

python - 拥有不可散列的类是不是 unpythonic?

sql - 甲骨文 : Create table in another schema and grant select and insert on it from the same schema