pymssql默认关闭自动模式开启事务行为浅析
使用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默认关闭自动模式开启事务行为浅析的更多相关文章
- MySQL 在线开启&关闭GTID模式
MySQL 在线开启&关闭GTID模式 目录 MySQL 在线开启&关闭GTID模式 基本概述 在线开启GTID 1. 设置GTID校验ENFORCE_GTID_CONSISTENCY ...
- Windows开启关闭测试模式的方法(含开启测试模式失败的解决办法)
前言: 内含:Windows开启关闭测试模式的方法.开启测试模式失败的解决办法.win10进入bios的方式.BitLocker恢复方式. 对于互联网从业者来说 ...
- Android 6.0 默认关闭定位和GPS,开启后默认选省电
默认关闭定位和GPS 修改位置 frameworks/base/packages/SettingsProvider/res/values/defaults.xml <string name=&q ...
- mysql 开启事务
START TRANSACTION, COMMIT, and ROLLBACK Syntax 开始事务,提交和回滚语法 那些语句提供了控制事务的使用: 1.START TRANSACTION 或者BE ...
- // 关闭调试模式 define('APP_DEBUG', false);
调试模式的优势在于: 开启日志记录,任何错误信息和调试信息都会详细记录,便于调试: 关闭模板缓存,模板修改可以即时生效: 记录SQL日志,方便分析SQL: 关闭字段缓存,数据表字段修改不受缓存影响: ...
- [android] 手机卫士关闭自动更新
保存数据的四种方式,网络,广播提供者,SharedPreferences,数据库 获取SharedPreferences对象,通过getSharedPreferences()方法,参数:名称,模式 例 ...
- 解决Lost connection to MySQL server during query错误方法/Mysql关闭严格模式
使用Navicat 导入MySQL数据库的时候,出现了一个严重的错误,Lost connection to MySQL server during query,字面意思就是在查询过程中丢失连接到MyS ...
- ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化
聚合函数 名称 作用 Max() 最大值 Min() 最小值 Sum() 求和 Count() 计数 Avg() 平均值 关键字: aggregate 聚合查询通常都是配合分组一起使用的 关于数据库的 ...
- KingbaseES V8R6 ksql 关闭自动提交
背景 用过oracle或mysql的人都知道,做一个dml语句,如果发现做错了,还可以rollback,但在Kingbase ksql 中,如果执行一个dml,没有先运行begin; 的话,一执行完就 ...
随机推荐
- Eclipse利用Maven快速上手搭建MyBatis
一.what is maven? Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件. Maven 除了以程序构建能力为特色之外,还提供高级项目管理 ...
- Python——Pandas速查手册中文版
转自——http://blog.csdn.net/qq_33399185/article/details/60872853,非常感谢大神的整理! 还有图片版,转自——https://zhuanlan. ...
- 洛谷:P3384 [HNOI2004]宠物收养场
原题地址:https://www.luogu.org/problemnew/show/P3384 题目简述 给定一些序列(没有重复数字),每个序列支持: 给定一些数k(对于每个序列不重复),每次在序列 ...
- Object.keys方法详解
一.官方解释 Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 .如果对象的键-值都不 ...
- Bitmap简介
1. BitMap Bit-map的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省.(PS:划重点 ...
- [ZJOI2006]物流运输trans
Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...
- 探讨Microsoft Solution Framework(MSF)框架下管理的秘密
hello,同学们,同胞们,同志们,同龄们,这样们,那样们,们们们,我又回来写“论文”了,半年时间没见我发布任何博文,是不是认为我被潜规则了啊,哈哈.我想死你们了.好了,废话不多说,进入今天主题: ...
- Linux快速入门
一.Linux介绍 1.Linux是基于Unix的开源免费的操作系统 2.Linux的分类: (1)Linux根据市场需求不同,基本分为两个方向: 1)图形化界面版:注重用户体验,类似window操作 ...
- Travis CI持续集成使用
用好这个工具不仅可以提高效率,还能使开发流程更可靠和专业化,从而提高软件的价值.而且,它对于开源项目是免费的,不花一分钱,就能帮你做掉很多事情. 一.什么是持续集成? Travis CI 提供的是持续 ...
- js继承机制的实现
js继承机制的实现 1. 继承的概念 说明继承的最经典的例子:几何形状.实际上,几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形.矩形和五边形 ...