2015-10-20 26 views
5

私はPythonでスレッドにmysql接続を渡そうとしています。 ワーカークラス内のmysqlの初期化を行うと、エラーは発生しません。mysql接続をpythonスレッドに渡すとパイプが途切れる

しかし、接続にはコストがかかるかもしれないので、私は呼び出し元関数からmysql接続を渡してみました(下記のコードを参照)。しかし、これはこのエラーを投げつづけています。

(2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))

なぜか?私はそのは道ので、我々はMySQLの接続を渡すの

代わりにmysqlの接続

def worker(db): 
""" Distributes the workload for a thread 
""" 
while True: 
    item = queue_handler.get() 
    perform_insert(item, db) 
    queue_handler.task_done() 

def insert_bulk(params): 
""" Handles the insert 
""" 
    cntr = 0 
    res = [] 
    cannot_read = [] 
    (data, cms, report_id) = params 

    db = nmi_mysql.DB(CONFIG['earnings_db'], True) 

    for i in range(10): 
     thrd = threading.Thread(target=worker, args=(db,)) 
     thrd.deamon = True 
     thrd.start() 

    for row in data: 
     split_files = row.split(',') 

     if len(split_files) != 34: 
      cannot_read.append(split_files) 
      continue 

     now = datetime.datetime.now() 

     res.append(<some data to insert>) 

     if len(res) == 750 or cntr == len(data): 
      queue_handler.put([res, cms, report_id]) 
      res = [] 

     cntr += 1 

    queue_handler.join() 

    db.close() 

    return [len(res), cms] 

UPDATEを渡すと思いますが、私たちは、接続プールを作成したスレッドでそのプールを使用します。こうすることで、スレッドレベルでプールから接続するだけです。

+0

通常、データベース接続は異なるクライアントスレッド間では使用されません。これらは、_thread-safe_ではありません。誰もあなたに良い答えを提供していない場合は、各スレッドを同じスレッドに処理することをお勧めします。 –

+0

@LittleSanti代わりに接続プールを使用しました。本当にうまくいく。 – Ninz

+0

プールを使用しても、すべての接続を同じスレッド内で完全に処理する間は、接続を取得し、使用して解放します。理由は同じです。接続は通常、スレッドセーフではありません。 –

答えて

2

データベース接続はスレッドセーフではないため、あるスレッドから別のスレッドに渡すべきではありません。接続プールは要求間のオープンな接続を保持しているため、プールから接続を取得してクエリに使用し、解放する方が高速です。

このrelated answerには、データベース接続のスレッドセーフティに関する有用なリンクがいくつかあります。

+0

私の答えは主にコメントの要約です。私はちょうどそれを投稿したので、この質問は未回答の質問のリストから削除されます。 –

関連する問題