2011-03-16 4 views
3

mysql 데이터베이스에 임의의 데이터가있는 행을 삽입합니다. 일부 행을 삽입 한 후 연결시 녹색 글이 멈 춥니 다. 통계 인쇄 greenlet이 계속 실행 됨sqlalchemy + mysql 교착 상태

이는 하나의 mysql-connector 및 mysqldb 드라이버가있는 수의 작업자 (하나 포함)에서 발생합니다. sqlite가 정상적으로 작동합니다. 무슨 일

def patch(): 
    from gevent import monkey 
    monkey.patch_all() 

    # fix https://bugs.launchpad.net/myconnpy/+bug/712037 
    from mysql.connector.connection import MySQLConnection 
    MySQLConnection.get_characterset_info = MySQLConnection.get_charset 
patch() 

from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine 
from gevent import spawn, sleep 
from random import randrange 
from time import time 

class Stats(object): 
    def __init__(self): 
     self.inserts, self.faults = 0, 0 

    def run(self): 
     while True: 
      sleep(1) 
      print "%d %d %d" % (time(), self.inserts, self.faults) 
      self.inserts, self.faults = 0, 0 

class Victim(object): 
    metadata = MetaData() 
    Entry = Table(
     'entry', metadata, 
     Column('id', Integer, primary_key=True), 
     Column('junk', String(128), unique=True) 
    ) 

    def __init__(self, cs, stats): 
     self.e = create_engine(cs) 
     self.metadata.drop_all(self.e) 
     self.metadata.create_all(self.e) 
     self.stats = stats 

    def add(self, junk, i): 
     print i, 'connecting' 
     c = self.e.connect() 
     print i, 'connected' 
     t = c.begin() 
     try: 
      q = self.Entry.insert().values(junk=junk) 
      c.execute(q) 
      t.commit() 
      self.stats.inserts += 1 
     except Exception as e: 
      print i, 'EXCEPTION: ', e 
      t.rollback() 
      self.stats.faults += 1 
     print i, 'done' 

def flood(victim, i): 
    a, z, l = ord('a'), ord('z')+1, 100 
    while True: 
     victim.add(''.join(chr(randrange(a, z)) for _ in xrange(l)), i) 
     sleep(0) 

def main(n_threads, cs): 
    stats = Stats() 
    victim = Victim(cs, stats) 
    threads = [ spawn(flood, victim, i) for i in xrange(n_threads) ] 
    threads.append(spawn(stats.run)) 
    [t.join() for t in threads] 

#main(2, 'mysql://root:[email protected]/junk') 
main(1, 'mysql+mysqlconnector://root:[email protected]/junk') 

(난 이미 새로운 gevent에 고정되어 이해)

This

이 적용되지 않습니다? 다시 테스트

는 오류가 gevent없이 확인하지-에서 결코 다시 수영장으로 연결 그래서 난 그냥 사용 연결을 해제하는 것을 잊었다 서버 구성

+0

"모든 근로자 수"에 정확히 1 명의 근로자가 포함되어 있습니까? – Romain

+0

예 (정답) – ymv

답변

1

와 아마 뭔가를 지속. ...

def add(self, junk, i): 
    print i, 'connecting' 
    c = self.e.connect() 
    ... 
    try: 
     ... 
    except Exception as e: 
     ... 
    finally: 
     c.close() # <-- this returns conenction into pool 
    print i, 'done'