联系我们 - 广告服务
您的当前位置:官网首页 > 资讯 > 热评 >

pymssql默认关闭自动模式开启事务行为浅析

来源: 编辑: 时间:2019-09-06
导读:

使用python采集sql server数据库服务器磁盘信息时,遇到了一个错误“config statement cannot be used inside a user transaction.db-lib error message 20018, severity 16”,那么为什么遇到这个错误呢? 其实很简单,就是因为sql server事务中不允许使用reconfigure,我们可以简单模拟构造一下这个错误,如下所示:

 

begin tran
  exec sp_configure 'show advanced options', 1
  reconfigure with override;
commit tran;

 

 

 

我的python脚本中,访问数据库的sql没有使用事务,那么是否pymssql中默认会开启事务呢? 我们可以构造一个python脚本访问sql server 数据库,然后我们使用sql profile跟踪一下,就基本上能知道是否pymssql会默认开启事务。python脚本trantest.py如下所示:

 

# -*- coding: utf-8 -*-
'''
-------------------------------------------------------------------------------------------
--  script name  :  trantest.py
-------------------------------------------------------------------------------------------
'''
import pymssql
import logging
import os.path
import os
import base64
from cryptography.fernet import fernet
 
 
 
 
 
key=bytes,encoding="utf8")
cipher_suite = fernet
with open as file_object:
  for line in file_object:
  encryptedpwd = line
decrypt_pwd = )
password_decrypted = bytes.decode #convert to string
env_db_user=os.environ.get
db_user=base64.b64decode)
 
 
dest_db_conn = pymssql.connect,
  user=bytes.decode,
  password=password_decrypted,
  database='master',
  charset="utf8");
 
sub_cursor = dest_db_conn.cursor
 
 
sub_cursor.execute as recordnum from msdb.dbo.sysmail_account')
result_rows =sub_cursor.fetchone
 
print
 
#dest_db_conn.commit
dest_db_conn.close

 

如下截图所示,我们发现pymssql会对任何访问sql server的sql加上begin tran,也许眼尖的同学发现了端倪,sql profile捕获的sql,有begin tran,但是没有commit tran,这个是因为上面的python代码中没有提交事务

 

 

 

 

修改上面python代码,在关闭数据库连接前,加上一行代码dest_db_conn.commit,然后重复上面实验就能看到commit tran了,如下所示:

 

dest_db_conn.commit
  dest_db_conn.close


 

 

 

那么pymssql中是否可以关闭事务呢? 因为有些普通、简单的查询,根本没有必要使用事务,其实pymmsql的connection接口其实是提供了这么一个功能的,官方文档的介绍如下:

 

connection object methods

 

connection.autocommit

where status is a boolean value. this method turns autocommit mode on or off.

by default, autocommit mode is off, what means every transaction must be explicitly committed if changed data is to be persisted in the database.

you can turn autocommit mode on, what means every single operation commits itself as soon as it succeeds.

a pymssql extension to the db-api 2.0.

 

 

我们知道,sql server在默认情况下数据库连接处于自动提交模式,每个sql命令一旦被执行便提交给数据库,一旦提交就无法回滚。 在数据库中不支持事务的情况下,自动提交模式是唯一支持的模式。 在此类数据库语句仅在提交后可以执行它们并没有方法回滚它们;它们因此始终处于自动提交模式.

 

那么我们测试一下就会发现autocommit=true的情况下,pymmsql不会自动给sql加上begin tran了

 

修改前代码:

 

dest_db_conn = pymssql.connect,
  user=bytes.decode,
  password=password_decrypted,
  database='master',
  charset="utf8");





 

修改后代码:

 

 

dest_db_conn = pymssql.connect,
  user=bytes.decode,
  password=password_decrypted,
  database='master',
  charset="utf8",





  autocommit=true);

 

 

关于pymssql默认情况下会关闭自动提交模式开启事务的行为,一定要小心,如果你sql脚本里面有dml操作而且忘记加commit时,那么可能造成很多不必要的阻塞。而且相信很多不明所以的同学还会一脸懵逼。

 

 

 

参考资料:

 

  https://github.com/pymssql/pymssql/issues/460

 

 

责任编辑:

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

网友评论:

在“\templets\demo\comments.htm”原来的内容全部删除,插入第三方评论代码,如果不需要评论功能,删除comments.html里面的内容即可
推荐使用友言、多说、畅言(需备案后使用)等社会化评论插件

Copyright © 2018 k8凯发国际娱乐k8凯发国际娱乐-k8凯发国际娱乐下载-k8凯发官方 All Rights Reserved Power by DedeCms
本站所有资讯来源于网络 如有侵权请联系QQ:9490489
Top