pythonsqlite事务_python sqlite3 的事务控制
Python sqlite3 的事務控制
官方文檔的描述:
Controlling Transactions
By default, the?sqlite3?module opens transactions implicitly before a Data Modification Language (DML) statement (i.e.?INSERT/UPDATE/DELETE/REPLACE), and commits transactions implicitly before a non-DML, non-query statement (i. e. anything other than?SELECT?or the aforementioned).
So if you are within a transaction and issue a command like?CREATE?TABLE?...,?VACUUM,?PRAGMA, thesqlite3?module will commit implicitly before executing that command. There are two reasons for doing that. The first is that some of these commands don’t work within transactions. The other reason is that pysqlite needs to keep track of the transaction state (if a transaction is active or not).
You can control which kind of?BEGIN?statements sqlite3 implicitly executes (or none at all) via the?isolation_level?parameter to the?connect()?call, or via the?isolation_level?property of connections.
(譯文:你能控制sqlite3默認執行的BEGIN語句類型(或者什么類型都不),這是通過設置connect()函數的isolation_level?參數,或connection對象的isolation_level屬性實現的。)
If you want?autocommit mode, then set?isolation_level?to None.
(譯文:如果想使用自動提交模式,設置isolation_level為None。)
Otherwise leave it at its default, which will result in a plain “BEGIN” statement, or set it to one of SQLite’s supported isolation levels: “DEFERRED”, “IMMEDIATE” or “EXCLUSIVE”.
(譯文:不設置isolation_level(使用默認)將會執行樸素的BEGIN語句(即下文sql語句圖中,BEGIN或BEGINTRANSACTION),或者設置為“DEFERRED”, “IMMEDIATE” 或“EXCLUSIVE”(即BEGIN DEFERRED/IMMEDIATE/EXCLUSIVETRANSACTION)。)
isolation_level控制的是什么
從上文我們看到,這個變量與BEGIN語句的模式有關,可選值為 “None“,“空“(不設置),“DEFERRED”, “IMMEDIATE” ,“EXCLUSIVE”
設置為None即自動提交,即每次寫數據庫都提交。
官網文檔前兩段寫的是智能提交,在某些語句自動開啟事務,執行某些語句前自動commit。
后邊四個是什么?
注:原文中begin-stmt應該是begin-statement的縮寫
這是描述sql語句語法的圖,即:
BEGIN TRANSACTION
BEGIN
BEGIN DEFERRED TRANSACTION
BEGIN DEFERRED
...
情況就明了了,isolation_level決定開啟事務時使用的是BEGIN TRANSACTION, BEGIN DEFERRED TRANSACTION, BEGIN IMMEDIATE TRANSACTION, BEGIN EXCLUSIVE TRANSACTION中的那種。
我是這么認為的,immediate 是begin語句處獲得PENDING鎖,deferred是獲取RESERVED鎖,update,delete,insert等寫語句出現時才獲得PENDING鎖,exclusive是獲取EXCLUSIVE排他鎖
isolation_level為None是開啟自動commit功能,非None是設置BEGIN的類型,開啟智能commit。
我理解為:1.BEGIN是自動開啟的 2.設為None每次寫數據庫都會自動commit?3.設為其他會在某些語句前自動commit,其他地方想立即commit要手動執行。
例子來了!
智能commit
import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table people (num, age)")
num = 1
age = 2 * num
while num <= 1000000:
cur.execute("insert into people values (?, ?)", (num, age))
num += 1
age = 2 * num
cur.execute("select count(*) from people")
print cur.fetchone()
保存為test.py執行之
# time python test.py
(1000000,)
real ? ?0m6.537s
user ? ?0m6.440s
sys ? ? 0m0.086s
自動commit
import sqlite3
con = sqlite3.connect(":memory:",isolation_level=None)
cur = con.cursor()
cur.execute("create table people (num, age)")
num = 1
age = 2 * num
while num <= 1000000:
cur.execute("insert into people values (?, ?)", (num, age))
num += 1
age = 2 * num
cur.execute("select count(*) from people")
print cur.fetchone()
執行之
# time python test.py
(1000000,)
real ? ?0m10.693s
user ? ?0m10.569s
sys ? ? 0m0.099s
智能commit用時6秒,自動commit用時10秒 (例子是寫內存,如果寫文件速度會更慢,建議改為寫100條數據)
智能commit
優點:速度快,單進程情況下運行良好
缺點:多個控制流并發操作數據庫時,這邊寫完了,另一邊可能讀不出來
克服缺點:每次寫完數據,手動執行commit
自動commit
優點:每次寫數據庫都能保證確實寫入了,防止并發操作數據庫時出現邏輯問題
缺點:太慢了!!!
克服缺點:批量操作前手動BEGIN TRANSACTION,操作后手動COMMIC
克服缺點的例子
智能commit時實現即時commit
# coding:utf-8
import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table people (num, age)")
num = 1
age = 2 * num
while num <= 1000000:
cur.execute("insert into people values (?, ?)", (num, age))
con.commit() # 關鍵在這里
num += 1
age = 2 * num
cur.execute("select count(*) from people")
print cur.fetchone()
time python test.py
(1000000,)
real ? ?0m20.797s
user ? ?0m20.611s
sys ? ? 0m0.156s
自動commit時阻止即時commit
# coding:utf-8
import sqlite3
con = sqlite3.connect(":memory:",isolation_level=None)
cur = con.cursor()
cur.execute("create table people (num, age)")
num = 1
age = 2 * num
cur.execute("BEGIN TRANSACTION") # 關鍵點
while num <= 1000000:
cur.execute("insert into people values (?, ?)", (num, age))
num += 1
age = 2 * num
cur.execute("COMMIT") #關鍵點
cur.execute("select count(*) from people")
print cur.fetchone()
# time python test.py
(1000000,)
real ? ?0m6.649s
user ? ?0m6.555s
sys ? ? 0m0.076s
這次,智能commit用時20秒(性能下降很多),自動commit用時6秒?,完全反過來了
總結
以上是生活随笔為你收集整理的pythonsqlite事务_python sqlite3 的事务控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql服务器文件夹共享,sqlserve
- 下一篇: python组成结构_Python数据分