我想知道从性能角度来看哪个是更好的选择,即插入行后我们应该使用 connection.commit()
还是 cursor.execute('commit')
考虑到我使用的是 Oracle 数据库。
最佳答案
根据文档,唯一明显的区别是两者属于不同的对象
Connection.commit() Commit any pending transactions to the database.
Cursor.execute() Execute a statement against the database
- 如果同一连接有多个游标,
connection.commit()
将提交属于程序中任何游标的任何待处理事务。 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/