Skip to content

Instantly share code, notes, and snippets.

@omsobliga
Last active August 15, 2016 02:56
Show Gist options
  • Save omsobliga/e5ef4cf0f98e79dd53bf06b4752642c4 to your computer and use it in GitHub Desktop.
Save omsobliga/e5ef4cf0f98e79dd53bf06b4752642c4 to your computer and use it in GitHub Desktop.
用多进程模拟数据库事务在并发环境下的表现
#!/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