我现在通过pyodbc同时处理2个表。 在完成处理之前,我想在2个表上放置锁,以便在我完成之前没有人可以更改2个表。 我该怎么办?
我尝试了以下操作,但失败并显示错误。
import pyodbc
conn = pyodbc.connect("conn_str")
conn.execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;")
conn.execute("begin transaction trans;")
cur1 = conn.execute("select * from tbl1;")
cur2 = conn.execute("select * from tbl2;")
... some processing at cur1 and cur2 at python ...
conn.execute("commit transaction trans;")
但是,当执行“ cur2 = conn.execute(“ select * from tbl2;”)“时出现以下错误
[Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt (0) (SQLExecDirectW)
我的代码有什么问题吗?非常感谢您的帮助。
答案 0 :(得分:0)
最初,每个连接只能将SQL Server ODBC限制为一个活动的hstmt
(相当于pyodbc.cursor
的ODBC)。稍后,Microsoft在SQL Server ODBC中添加了MARS(多个活动结果集)功能,但是默认情况下该功能为“关闭”。
这段代码
import pyodbc
import sys
print(f"Python version {sys.version}") # Python version 3.6.4 ...
print(f"pyodbc version {pyodbc.version}") # pyodbc version 4.0.24
conn_str = (
r'DRIVER=ODBC Driver 17 for SQL Server;'
r'SERVER=.\SQLEXPRESS;'
r'DATABASE=myDb;'
r'Trusted_Connection=yes;'
)
cnxn = pyodbc.connect(conn_str, autocommit=True)
cnxn.set_attr(pyodbc.SQL_ATTR_TXN_ISOLATION, pyodbc.SQL_TXN_SERIALIZABLE)
cnxn.autocommit = False # enable transactions
cur1 = cnxn.execute("SELECT 1 AS x UNION ALL SELECT 2 AS x")
cur2 = cnxn.execute("SELECT 'foo' AS y UNION ALL SELECT 'bar' AS y")
print(cur1.fetchone())
print(cur2.fetchone())
print(cur1.fetchone())
print(cur2.fetchone())
失败
Traceback (most recent call last):
File "C:/Users/Gord/PycharmProjects/py3pyodbc_demo/main.py", line 18, in <module>
cur2 = cnxn.execute("SELECT 'foo' AS y UNION ALL SELECT 'bar' AS y")
pyodbc.Error: ('HY000', '[HY000] [Microsoft][ODBC Driver 17 for SQL Server]Connection is busy with results for another command (0) (SQLExecDirectW)')
但是,如果我们在连接字符串中添加MARS_Connection=yes
conn_str = (
r'DRIVER=ODBC Driver 17 for SQL Server;'
r'SERVER=.\SQLEXPRESS;'
r'DATABASE=myDb;'
r'Trusted_Connection=yes;'
r'MARS_Connection=yes;'
)
然后代码起作用。
不幸的是,您使用的是古老的DRIVER=SQL Server
,它太旧了,无法支持MARS_Connection=yes
,因此您的选择是