使用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没有使用事务(没有BEGIN TRAN ... COMMIT TRAN),那么是否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(os.environ.get('key'),encoding="utf8")

cipher_suite = Fernet(key)

with open('/home/konglb/python/conf/ms_db_conf.bin', 'rb') as file_object:

    for line in file_object:

        encryptedpwd = line

decrypt_pwd = (cipher_suite.decrypt(encryptedpwd))

password_decrypted = bytes(decrypt_pwd).decode("utf-8") #convert to string

env_db_user=os.environ.get('db_user')

db_user=base64.b64decode(bytes(env_db_user, encoding="utf8"))

 

 

dest_db_conn = pymssql.connect(host=os.environ.get('db_host'),

                               user=bytes.decode(db_user),

                               password=password_decrypted,

                               database='master',

                               charset="utf8");

 

sub_cursor = dest_db_conn.cursor(as_dict=True)

 

 

sub_cursor.execute('SELECT COUNT(*) AS RecordNum FROM msdb.dbo.sysmail_account')

result_rows =sub_cursor.fetchone()

 

print(result_rows["RecordNum"])

 

#dest_db_conn.commit()

dest_db_conn.close()

如下截图所示,我们发现pymssql会对任何访问SQL Server的SQL加上BEGIN TRAN,也许眼尖的同学发现了端倪,SQL Profile捕获的SQL,有BEGIN TRAN,但是没有COMMIT TRAN,这个是因为上面的Python代码中没有提交事务(#dest_db_conn.commit() 注释了)

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

dest_db_conn.commit()
   dest_db_conn.close()

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

Connection object methods

Connection.autocommit(status)

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在默认情况下数据库连接处于自动提交模式(autocommit mode),每个SQL命令一旦被执行便提交给数据库,一旦提交就无法回滚。 在数据库中不支持事务的情况下,自动提交模式是唯一支持的模式。 在此类数据库语句仅在提交后可以执行它们并没有方法回滚它们;它们因此始终处于自动提交模式.

那么我们测试一下就会发现autocommit=True的情况下,pymmsql不会自动给SQL加上BEGIN TRAN了(测试期间,犯了个迷糊,弄混了一个前提条件,而且没有充分测试,就做出了一个相反的结论,后续自己一直折腾时才发现这个问题)

修改前代码:

dest_db_conn = pymssql.connect(host=os.environ.get('db_host'),
                               user=bytes.decode(db_user),
                               password=password_decrypted,
                               database='master',
                               charset="utf8");

修改后代码:

dest_db_conn = pymssql.connect(host=os.environ.get('db_host'),
                               user=bytes.decode(db_user),
                               password=password_decrypted,
                               database='master',
                               charset="utf8",

autocommit=True);

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

参考资料:

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

http://pymssql.org/en/stable/ref/pymssql.html#connection-object-methods

pymssql默认关闭自动模式开启事务行为浅析的更多相关文章

  1. MySQL 在线开启&关闭GTID模式

    MySQL 在线开启&关闭GTID模式 目录 MySQL 在线开启&关闭GTID模式 基本概述 在线开启GTID 1. 设置GTID校验ENFORCE_GTID_CONSISTENCY ...

  2. Windows开启关闭测试模式的方法(含开启测试模式失败的解决办法)

    前言:           内含:Windows开启关闭测试模式的方法.开启测试模式失败的解决办法.win10进入bios的方式.BitLocker恢复方式.           对于互联网从业者来说 ...

  3. Android 6.0 默认关闭定位和GPS,开启后默认选省电

    默认关闭定位和GPS 修改位置 frameworks/base/packages/SettingsProvider/res/values/defaults.xml <string name=&q ...

  4. mysql 开启事务

    START TRANSACTION, COMMIT, and ROLLBACK Syntax 开始事务,提交和回滚语法 那些语句提供了控制事务的使用: 1.START TRANSACTION 或者BE ...

  5. // 关闭调试模式  define('APP_DEBUG', false);

    调试模式的优势在于: 开启日志记录,任何错误信息和调试信息都会详细记录,便于调试: 关闭模板缓存,模板修改可以即时生效: 记录SQL日志,方便分析SQL: 关闭字段缓存,数据表字段修改不受缓存影响: ...

  6. [android] 手机卫士关闭自动更新

    保存数据的四种方式,网络,广播提供者,SharedPreferences,数据库 获取SharedPreferences对象,通过getSharedPreferences()方法,参数:名称,模式 例 ...

  7. 解决Lost connection to MySQL server during query错误方法/Mysql关闭严格模式

    使用Navicat 导入MySQL数据库的时候,出现了一个严重的错误,Lost connection to MySQL server during query,字面意思就是在查询过程中丢失连接到MyS ...

  8. ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化

    聚合函数 名称 作用 Max() 最大值 Min() 最小值 Sum() 求和 Count() 计数 Avg() 平均值 关键字: aggregate 聚合查询通常都是配合分组一起使用的 关于数据库的 ...

  9. KingbaseES V8R6 ksql 关闭自动提交

    背景 用过oracle或mysql的人都知道,做一个dml语句,如果发现做错了,还可以rollback,但在Kingbase ksql 中,如果执行一个dml,没有先运行begin; 的话,一执行完就 ...

随机推荐

  1. SUSE CaaS Platform 4 - 使用 Ceph RBD 作为持久存储 (静态)

    1.所有节点安装 # zypper -n in ceph-common 复制 ceph.conf 到 worker 节点上 # scp admin:/etc/ceph/ceph.conf /etc/c ...

  2. 什么是VR中的Locomotion?

    Locomotion,本文中我称之为移位,是VR研究中最重要的话题之一.因为它属于VR中三大元老级操作(Selection选择,Manipulation操纵物体,Locomotion移位),其中,前两 ...

  3. 那些初学python犯过的小白错误(学习笔记1)

    一.关于print函数 区别于c和py2,py3的print的正确形式如下:print("hello world") 错误语句:print"hello world&quo ...

  4. Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门

    1. 什么是响应式编程 在计算机中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流 ...

  5. 使用Jmeter并发websocket协议项目

    1.安装Jmeter 网址:http://jmeter.apache.org/下载 2.启动Jmeter \apache-jmeter-5.1.1\bin\jmeter.bat 3.安装‘Plugin ...

  6. [AI开发]视频结构化类应用的局限性

    算法不是通用的,基于深度学习的应用系统不但做不到通用,即使对于同一类业务场景,还需要为每个场景做定制.特殊处理,这样才能有可能到达实用标准.这种局限性在计算机视觉领域的应用中表现得尤其突出,本文介绍基 ...

  7. PS 2018安装教程

    写在前面:简单的PS是每一个前端开发者必备的技能,官方的PS安装包是需要购买的,但是可以免费的体验7天. 01 下载安装包,根据自己电脑的系统 Photoshop CC2018/64位下载地址:链接: ...

  8. F#周报2019年第42期

    新闻 TypeShape的性能 .NET Core 3.0包含.NET Framework API移植项目 宣告.NET Core 3.1预览版1 .NET Core 3.1预览版1中ASP.NET ...

  9. C# 控件 RichTextBox 显示行号,并且与Panel相互联动

    我们在使用到WINFORM窗体工作中,要求RichTextBox 加入行号: 之前有看到大牛们写的,但是太复杂繁多,而且有用双TextBox进行联动,非常不错,今天我们尝试RichTextBox +P ...

  10. opencv::模糊图像

    Smooth/Blur 是图像处理中最简单和常用的操作之一,使用该操作的原因之一就为了给图像预处理时候减低噪声 使用Smooth/Blur操作其背后是数学的卷积计算,通常这些卷积算子计算都是线性操作, ...