mysql.connector 事務總結


mysql.connector事務總結:

connection.autocommit = 0 (默認值)

事務處理

使用 connection.commit()方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-

'''mysql.connector事務總結:

connection.autocommit = 0 (默認值)
事務處理
    使用 connection.commit()方法


分析:
    智能commit狀態: 
        connection.autocommit = 0 (默認值)
            默認不提交
        事務處理
            可以使用 connection.commit()方法來進行提交
    
    自動commit狀態:
        connection.autocommit = 0
            這樣,在任何DML操作時,都會自動提交
        事務處理
            connection.execute("BEGIN;")
            connection.commit()
        如果不使用事務, 批量添加數據相對緩慢

    兩種方式, 事務耗時差別不大
    自動commit的速度受網絡傳輸影響大

比較數據:
    192.168.1.107, count=100
        默認commit事務耗時: 0.152
        自動commit, cursor.execute("COMMIT;")耗時: 0.139
        自動commit2, connection.commit()耗時: 0.143
        自動commit,非事務耗時: 0.397
        
    192.168.1.107, count=1000
        默認commit事務耗時: 1.365
        自動commit, cursor.execute("COMMIT;")耗時: 1.389
        自動commit2, connection.commit()耗時: 1.291
        自動commit,非事務耗時: 3.871
    
    192.168.6.226, count=100
        默認commit事務耗時: 0.178
        自動commit, cursor.execute("COMMIT;")耗時: 0.183
        自動commit2, connection.commit()耗時: 0.192
        自動commit,非事務耗時: 1.965

'''


import sys
import time


class Elapse_time(object):
    '''耗時統計工具'''
    def __init__(self, prompt=''):
        self.prompt = prompt
        self.start = time.time()
        
    def __del__(self):
        print('%s耗時: %.3f' % (self.prompt, time.time() - self.start))
CElapseTime = Elapse_time

import mysql.connector

# -------------------------------------------------------------------------------
# 測試
#

db_parameters = {'host': '192.168.1.107',
'database': 'test',
                 'charset': 'utf8'}
db_parameters1 = {'host': '192.168.6.226',
'database': 'test',
                 'charset': 'utf8'}

def prepare(isolation_level = ''):
    connection = mysql.connector.MySQLConnection(**db_parameters)
    cursor = connection.cursor()
    cursor.execute("create table IF NOT EXISTS  people (num int, age int)")
    cursor.execute('delete from people')
    connection.commit()
    return connection, connection.cursor()

def db_insert_values(cursor, count):
    num = 1 
    age = 2 * num 
    
    while num <= count:
        cursor.execute("insert into people values (%s, %s)", (num, age))
        num += 1
        age = 2 * num 


def study_case1_default_commit_manual(count):
    connection, cursor = prepare()
    
    elapse_time = Elapse_time('  默認commit事務')
    db_insert_values(cursor, count)
    connection.commit()
    
    cursor.execute("select count(*) from people")
    print (cursor.fetchone())


def study_case2_autocommit_transaction(count):
    connection, cursor = prepare(isolation_level = None)
    connection.autocommit = 1
    
    elapse_time = Elapse_time('  自動commit, cursor.execute("COMMIT;")')
    cursor.execute("BEGIN;") # 關鍵點
    db_insert_values(cursor, count)
    cursor.execute("COMMIT;")  #關鍵點
    
    cursor.execute("select count(*) from people;")
    print (cursor.fetchone())


def study_case3_autocommit_transaction2(count):
    connection, cursor = prepare(isolation_level = None)
    connection.autocommit = 1
    
    elapse_time = Elapse_time('  自動commit2, connection.commit()')
    cursor.execute("BEGIN;") # 關鍵點
    db_insert_values(cursor, count)
    connection.commit()
    
    cursor.execute("select count(*) from people;")
    print (cursor.fetchone())


def study_case4_autocommit_no_transaction(count):
    connection, cursor = prepare(isolation_level = None)
    connection.autocommit = 1
    
    elapse_time = Elapse_time('  自動commit,非事務')
    db_insert_values(cursor, count)
    
    cursor.execute("select count(*) from people;")
    print (cursor.fetchone())


def main(config):
    output = []
    db = mysql.connector.Connect(**config)
    cursor = db.cursor()

    # Drop table if exists, and create it new
    stmt_drop = "DROP TABLE IF EXISTS names"
    cursor.execute(stmt_drop)

    stmt_create = """
    CREATE TABLE names (
        id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
        name VARCHAR(30) DEFAULT '' NOT NULL,
        cnt TINYINT UNSIGNED DEFAULT 0,
        PRIMARY KEY (id)
    ) ENGINE=InnoDB"""
    cursor.execute(stmt_create)

    warnings = cursor.fetchwarnings()
    if warnings:
        ids = [ i for l,i,m in warnings]
        output.append("Oh oh.. we got warnings..")
        if 1266 in ids:
            output.append("""
            Table was created as MYISAM, no transaction support.

            Bailing out, no use to continue. Make sure InnoDB is available!
            """)
            db.close()
            return

    # Insert 3 records
    output.append("Inserting data")
    names = ( ('Geert',), ('Jan',), ('Michel',) )
    stmt_insert = "INSERT INTO names (name) VALUES (%s)"
    cursor.executemany(stmt_insert, names)

    # Roll back!!!!
    output.append("Rolling back transaction")
    db.rollback()

    # There should be no data!
    stmt_select = "SELECT id, name FROM names ORDER BY id"
    cursor.execute(stmt_select)
    rows = None
    try:
        rows = cursor.fetchall()
    except mysql.connector.InterfaceError as e:
        raise

    if rows == []:
        output.append("No data, all is fine.")
    else:
        output.append("Something is wrong, we have data although we rolled back!")
        output.append(rows)
        cursor.close()
        db.close()
        return output

    # Do the insert again.
    cursor.executemany(stmt_insert, names)

    # Data should be already there
    cursor.execute(stmt_select)
    output.append("Data before commit:")
    for row in cursor.fetchall():
        output.append("%d | %s" % (row[0], row[1]))

    # Do a commit
    db.commit()

    cursor.execute(stmt_select)
    output.append("Data after commit:")
    for row in cursor.fetchall():
        output.append("%d | %s" % (row[0], row[1]))

    # Cleaning up, dropping the table again
    cursor.execute(stmt_drop)

    cursor.close()
    db.close()
    return output

if __name__ == '__main__':
    #out = main(db_parameters)
    #print('\n'.join(out))
    
    count = 1000
    prepare()
    for i in range(1):
        study_case1_default_commit_manual(count)
        study_case2_autocommit_transaction(count)
        study_case3_autocommit_transaction2(count)
        study_case4_autocommit_no_transaction(count)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM