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)