python写数据库校验_python 验证 sqlite数据库隔离级别

sqlite3支持三种数据库锁级别,也叫隔离级别。下面代码中我们对数据库中task表进行更新,然后由另一个线程读取这个表的数据

import

logging

import sqlite3

import

sys

import

threading

import

time

logging.

basicConfig

(

level

=

logging.

DEBUG

,

format

=

'%(asctime)s (%(threadName)-10s) %(message)s'

,

)

db_filename

=

'todo.db'

isolation_level

=

sys.

argv

[

1

]

def writer

(

):

my_name

=

threading.

currentThread

(

).

name

with sqlite3.

connect

(db_filename

,isolation_level

=isolation_level

)

as conn:

cursor

=conn.

cursor

(

)

cursor.

execute

(

'update task set priority=priority+1'

)

logging.

debug

(

'waiting to synchronize'

)

ready.

wait

(

)

# synchronize threads

time.

sleep

(

1

)

conn.

commit

(

)

logging.

debug

(

'CHANGES COMMITTED'

)

return

def reader

(

):

my_name

=

threading.

currentThread

(

).

name

with sqlite3.

connect

(db_filename

,isolation_level

=isolation_level

)

as conn:

cursor

=conn.

cursor

(

)

logging.

debug

(

'waiting to synchronize'

)

ready.

wait

(

)

#synchronize threads

cursor.

execute

(

'select * from task'

)

logging.

debug

(

'SELECT EXECUTED'

)

results

=cursor.

fetchall

(

)

logging.

debug

(

'result fetched'

)

return

if __name__

==

'__main__':

ready

=

threading.

Event

(

)

threads

=

[

threading.

Thread

(name

=

'Reader 1'

,target

=reader

)

,

threading.

Thread

(name

=

'Reader 2'

,target

=reader

)

,

threading.

Thread

(name

=

'Writer 1'

,target

=writer

)

,

threading.

Thread

(name

=

'Writer 2'

,target

=writer

)

,

]

[t.

start

(

)

for t

in threads

]

time.

sleep

(

1

)

logging.

debug

(

'setting ready'

)

ready.

set

(

)

[t.

join

(

)

for t

in threads

]

以下程序演示了,分别使用不同的锁级别操作数据库的结果。

1.使用延迟锁:这种模式是sqlite3的默认模式,也就是只在发生改变的时候才会锁上被更新的记录。

$ python sqlite3_isolation_levels.

py DEFERRED

其输出结果为:

2011-12-13 11:19:38,183

(Reader 1

) waiting to synchronize

2011-12-13 11:19:38,183

(Reader 2

) waiting to synchronize

2011-12-13 11:19:38,187

(Writer 1

) waiting to synchronize

2011-12-13 11:19:39,184

(MainThread

) setting ready

2011-12-13 11:19:39,186

(Reader 1

) SELECT EXECUTED

2011-12-13 11:19:39,186

(Reader 2

) SELECT EXECUTED

2011-12-13 11:19:39,187

(Reader 1

) result fetched

2011-12-13 11:19:39,187

(Reader 2

) result fetched

2011-12-13 11:19:40,243

(Writer 1

) CHANGES COMMITTED

2011-12-13 11:19:40,316

(Writer 2

) waiting to synchronize

2011-12-13 11:19:41,368

(Writer 2

) CHANGES COMMITTED

2.使用“立即锁”:这种模式下一但要更新数据库,会立即锁上这条记录,直到事务提交才会打开锁。

$ python sqlite3_isolation_levels.

py IMMEDIATE

其输出结果为:

2011-12-13 11:27:04,053

(Reader 1

) waiting to synchronize

2011-12-13 11:27:04,053

(Reader 2

) waiting to synchronize

2011-12-13 11:27:04,058

(Writer 1

) waiting to synchronize

2011-12-13 11:27:05,055

(MainThread

) setting ready

2011-12-13 11:27:05,056

(Reader 1

) SELECT EXECUTED

2011-12-13 11:27:05,058

(Reader 1

) result fetched

2011-12-13 11:27:05,058

(Reader 2

) SELECT EXECUTED

2011-12-13 11:27:05,058

(Reader 2

) result fetched

2011-12-13 11:27:06,111

(Writer 1

) CHANGES COMMITTED

2011-12-13 11:27:06,188

(Writer 2

) waiting to synchronize

2011-12-13 11:27:07,244

(Writer 2

) CHANGES COMMITTED

3.使用“排他锁”:这种锁会对所有的读写操作都上锁。这种锁一般用于对数据库性能要求较高的情况,因为一旦上锁,这个数据库连接就只能为一个使用者使用。

$ python sqlite3_isolation_levels.

py EXCLUSIVE

其输出结果为:

2011-12-13 11:32:37,276

(Reader 1

) waiting to synchronize

2011-12-13 11:32:37,276

(Reader 2

) waiting to synchronize

2011-12-13 11:32:37,278

(Writer 1

) waiting to synchronize

2011-12-13 11:32:38,279

(MainThread

) setting ready

2011-12-13 11:32:39,336

(Writer 1

) CHANGES COMMITTED

2011-12-13 11:32:39,367

(Reader 2

) SELECT EXECUTED

2011-12-13 11:32:39,368

(Reader 1

) SELECT EXECUTED

2011-12-13 11:32:39,368

(Reader 2

) result fetched

2011-12-13 11:32:39,371

(Reader 1

) result fetched

2011-12-13 11:32:39,398

(Writer 2

) waiting to synchronize

2011-12-13 11:32:40,453

(Writer 2

) CHANGES COMMITTED

当然我们也可以把锁级别设置为None,这样就是所谓的自动提交模式。我们对上面的代码修改一下,把isolation_level的值设置为None,然后去掉conn.commit()。这样每次的数据库修改会自动提交到数据库。代码如下:

import

logging

import sqlite3

import

sys

import

threading

import

time

logging.

basicConfig

(

level

=

logging.

DEBUG

,

format

=

'%(asctime)s (%(threadName)-10s) %(message)s'

,

)

db_filename

=

'todo.db'

def writer

(

):

my_name

=

threading.

currentThread

(

).

name

with sqlite3.

connect

(db_filename

,isolation_level

=

None

)

as conn:

cursor

=conn.

cursor

(

)

cursor.

execute

(

'update task set priority=priority+1'

)

logging.

debug

(

'waiting to synchronize'

)

ready.

wait

(

)

# synchronize threads

time.

sleep

(

1

)

logging.

debug

(

'CHANGES COMMITTED'

)

return

def reader

(

):

my_name

=

threading.

currentThread

(

).

name

with sqlite3.

connect

(db_filename

,isolation_level

=

None

)

as conn:

cursor

=conn.

cursor

(

)

logging.

debug

(

'waiting to synchronize'

)

ready.

wait

(

)

#synchronize threads

cursor.

execute

(

'select * from task'

)

logging.

debug

(

'SELECT EXECUTED'

)

results

=cursor.

fetchall

(

)

logging.

debug

(

'result fetched'

)

return

if __name__

==

'__main__':

ready

=

threading.

Event

(

)

threads

=

[

threading.

Thread

(name

=

'Reader 1'

,target

=reader

)

,

threading.

Thread

(name

=

'Reader 2'

,target

=reader

)

,

threading.

Thread

(name

=

'Writer 1'

,target

=writer

)

,

threading.

Thread

(name

=

'Writer 2'

,target

=writer

)

,

]

[t.

start

(

)

for t

in threads

]

time.

sleep

(

1

)

logging.

debug

(

'setting ready'

)

ready.

set

(

)

[t.

join

(

)

for t

in threads

]

执行后的输出结果为:

2011-12-13 11:35:00,753

(Reader 1

) waiting to synchronize

2011-12-13 11:35:00,753

(Reader 2

) waiting to synchronize

2011-12-13 11:35:00,825

(Writer 1

) waiting to synchronize

2011-12-13 11:35:00,953

(Writer 2

) waiting to synchronize

2011-12-13 11:35:01,755

(MainThread

) setting ready

2011-12-13 11:35:01,756

(Reader 2

) SELECT EXECUTED

2011-12-13 11:35:01,756

(Reader 1

) SELECT EXECUTED

2011-12-13 11:35:01,757

(Reader 2

) result fetched

2011-12-13 11:35:01,757

(Reader 1

) result fetched

2011-12-13 11:35:02,755

(Writer 2

) CHANGES COMMITTED

2011-12-13 11:35:02,755

(Writer 1

) CHANGES COMMITTED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值