我正在使用pyodbc进行自动提交'设为false。
我假设如果只使用SELECT
个sql语句(没有INSERT
或UPDATE
),那么调用' commit'函数对DB无效。
如果我不打电话给#t;提交&#39>,pyodbc中是否有任何方法可以确定是否有任何未决的更改会丢失?
我一直在考虑使用pyodbc' getinfo'函数是SQLGetInfo的包装器,但无法为其找到任何合适的参数。
实际上我想要做的只是通知用户数据库中的数据将被更改,但我不想控制使用的SQL语句(仅SELECT
或者也是UPDATE
& INSERT
)因为有太多地方我需要检查它。
答案 0 :(得分:2)
不幸的是,pyodbc没有内置功能来检查未决的提交。
在SQL Server(从2008年开始)中,您可以使用database_transaction_state
表中的sys.dm_tran_database_transactions
字段在数据库级别检查挂起的提交。带有暂挂提交的事务状态应为4
。没有等待提交的人应该是3
。
在documentation中,提到的状态定义为:
3 =事务已初始化,但未生成任何日志 记录。
4 =交易已生成日志记录。
以下脚本检查了这个想法。
输出
Starting point, no pending transaction or commits
@@TRANCOUNT = 0
database_transaction_state = None
Disable autocommit
@@TRANCOUNT = 1
database_transaction_state = 3
Perform an Insert
@@TRANCOUNT = 1
database_transaction_state = 4
Explicit commit
@@TRANCOUNT = 1
database_transaction_state = 3
Enable autocommit
@@TRANCOUNT = 0
database_transaction_state = None
代码
import pyodbc
conn_param = {
"DRIVER": "{ODBC Driver 13 for SQL Server}",
"SERVER": "(localdb)\\ProjectsV13",
"DATABASE": "master"
}
conn_string = ";".join(["{}={}".format(k, v) for k, v in conn_param.items()])
conn = pyodbc.connect(conn_string, autocommit=True)
cursor = conn.cursor()
def check():
print("\t@@TRANCOUNT = {}".format(
cursor.execute("select @@TRANCOUNT").fetchval()
))
print("\tdatabase_transaction_state = {}".format(
cursor.execute("""
select database_transaction_state
from sys.dm_tran_database_transactions
where transaction_id = CURRENT_TRANSACTION_ID()
and database_id = (
select dbid from sys.sysprocesses where spid = @@SPID
)""").fetchval()
))
cursor.execute("DROP TABLE IF EXISTS testTable")
cursor.execute("SELECT * INTO testTable FROM (VALUES (1), (2), (3)) as x(a)")
print("Starting point, no pending transaction or commits")
check()
print("Disable autocommit")
conn.autocommit = False
check()
print("Perform an Insert")
cursor.execute("INSERT INTO testTable VALUES (4)")
check()
print("Explicit commit")
conn.commit()
check()
print("Enable autocommit")
conn.autocommit = True
check()
cursor.execute("DROP TABLE IF EXISTS testTable")
cursor.close()
conn.close()