pymssql預設關閉自動模式開啟事務行為淺析

来源:https://www.cnblogs.com/kerrycode/archive/2019/08/21/11391832.html
-Advertisement-
Play Games

使用Python採集SQL Server資料庫伺服器磁碟信息時,遇到了一個錯誤“CONFIG statement cannot be used inside a user transaction.DB-Lib error message 20018, severity 16”,那麼為什麼遇到這個錯誤... ...


使用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;

 

clip_image001

 

 

我的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() 註釋了)

 

 

clip_image002

 

 

修改上面Python代碼,在關閉資料庫連接前,加上一行代碼dest_db_conn.commit(),然後重覆上面實驗就能看到COMMIT TRAN了,如下所示:

 

dest_db_conn.commit()
   dest_db_conn.close()

 

clip_image003

 

 

那麼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時,那麼可能造成很多不必要的阻塞。而且相信很多不明所以的同學還會一臉懵逼。

 

 

 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 利用 Spring Boot Admin 進行項目監控管理 一、Spring Boot Admin 是什麼 Spring Boot Admin (SBA) 是一個社區開源項目,用於管理和監視 Spring Boot 應用程式。應用程式通過 的方式註冊到 Spring Boot 管理客戶端,或者通過 ...
  • 一、聯繫一個if語句 二、接受用戶輸入 三、簡寫括弧 四、源碼: d19_user_input_and_omit_brace.java 地址:https://github.com/ruigege66/Java/blob/master/d19_user_input_and_omit_brace.jav ...
  • 自1998年 JDK 1.0(Java 1.0) 發佈以來,Java 已經受到了學生、項目經理和程式員等一大批活躍用戶的歡迎。這一語言極富活力,不斷被用在大大小小的項目里。從 Java 1.1(1997年) 一直到 Java 7(2011年),Java 通過增加新功能,不斷得到良好的升級。Java ...
  • 基本類: AtomicInteger AtomicLong "AtomicBoolean" 數組類型: AtomicIntegerArray AtomicLongArray AtomicReferenceArray 介紹 由於在多線程條件下,如果對共用變數修改容易造成數據不一致的情況,所以對於共用變 ...
  • 最近一個朋友,在謀求架構師崗位的工作,經歷了魔都的一批互聯網公司的洗禮,讓他把面試經歷整理了一下,給大家一些經驗吧,希望各位後面去這些公司面試的時候,能有些心理準備。 還唄 地點:2號線金科路地鐵站(長泰廣場A座) 環境:環境還不錯,裝修偏簡約風,工位是互聯網公司那種排排坐。 投遞方式:拉勾網 面試 ...
  • 代理(proxy)分為2種: 靜態代理 動態代理 動態代理常用的有jdk動態代理、cglib代理。 靜態代理 1、新建User介面 2、新建實現類UserImpl 3、新建代理類UserProxy,也實現User介面,對目標對象(的方法)進行增強 4、使用代理。新建測試類Test 靜態代理的特點 代 ...
  • 一、前言 在Java中,工具類定義了一組公共方法,這篇文章將介紹Java中使用最頻繁及最通用的Java工具類。以下工具類、方法按使用流行度排名,參考數據來源於Github上隨機選取的5萬個開源項目源碼。 二、org.apache.commons.io.IOUtils closeQuietly:關閉一 ...
  • 一、定時任務實現的幾種方式: Timer 這是java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務。使用這種方式可以讓你的程式按照某一個頻度執行,但不能在指定時間運行。一般用的較少。 ScheduledExecutorService 也jdk ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...