Last active
August 15, 2016 02:56
-
-
Save omsobliga/e5ef4cf0f98e79dd53bf06b4752642c4 to your computer and use it in GitHub Desktop.
用多进程模拟数据库事务在并发环境下的表现
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
用多进程模拟数据库事务在并发环境下的表现。 | |
测试环境: | |
一个数据库 server, 4 核机器, 四个进程 | |
运行结果:: | |
run 0 process | |
run 1 process | |
run 2 process | |
run 3 process | |
process 52290 18 | |
process 52287 18 | |
process 52287 19 | |
process 52290 19 | |
process 52288 19 | |
process 52289 19 | |
process 52288 20 | |
process 52289 20 | |
可以看到进程 52287 和 52290 在运行时, 拿到的最大 id 都是 18, 随后分别写入 19 到数据库。 | |
说明数据库事务在执行时, 并非真正意义上的串行。 | |
但同一进程两次打印的数字都只相差一, 所以同一个事务中是可以重复读的, 不会受到其他事务执行的影响。 | |
""" | |
import multiprocessing | |
import os | |
from sqlalchemy import create_engine | |
def incr(): | |
engine = create_engine('mysql+mysqldb://root:@127.0.0.1/test') | |
conn = engine.connect() | |
with conn.begin(): | |
res = conn.execute('SELECT id FROM a ORDER BY id DESC LIMIT 1').scalar() | |
print 'process {}'.format(os.getpid()), res | |
conn.execute('INSERT INTO a (id) VALUE ({})'.format(res + 1)) | |
res = conn.execute('SELECT id FROM a ORDER BY id DESC LIMIT 1').scalar() | |
print 'process {}'.format(os.getpid()), res | |
def run_single_process(): | |
p = multiprocessing.Process(target=incr, args=()) | |
print 'start' | |
p.start() | |
p.join() | |
print 'end' | |
def run_multi_processes(): | |
pool = multiprocessing.Pool(processes=4) | |
for i in xrange(4): | |
print 'run {} process'.format(i) | |
pool.apply_async(incr, args=()) | |
pool.close() | |
pool.join() | |
if __name__ == '__main__': | |
run_multi_processes() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment