LINUX.ORG.RU

Как обратиться к MySQL одновременно из нескольких нитей на Python?


0

1

Код примерно такой:

import sys
import MySQLdb
import thread

cx = MySQLdb.connect (...)
cur = cx.cursor()
cur.execute("SET NAMES utf8;")
cur.execute("SET CHARACTER SET utf8;")
cur.execute("SET character_set_connection=utf8;")

def select():
  try:
    cur.execute ("SELECT product_id FROM product_feature;")
  except Exception,e:
    print "SQL Error: %s" % str(e)

n_t = 0
NTMAX = 15
for i in xrange (100):
  while (n_t > NTMAX):
    sys.stdout.write (".")
    time.sleep (0.2)
  n_t = n_t + 1
  thread.start_new (select, ())

print "Waiting ..."
while (n_t > 0):
  time.sleep (0.2);

Python вываливается с такой ошибкой?

$ python test.py
.SQL Error: (2006, 'MySQL server has gone away')
Segmentation fault (core dumped)

В чем проблема? Почему вылетает по SEGFAULT?

★★★★★

извините, а почему 3 раза выбирается кодировка? вы ему это доказываете? или ето так в MySQLDb?

ggrn ★★★★★
()

Вы только посмотрите на эту баку!

Ну бака же!

The MySQL protocol can not handle multiple threads using the same connection at once. Some earlier versions of MySQLdb utilized locking to achieve a threadsafety of 2. While this is not terribly hard to accomplish using the standard Cursor class (which uses ``mysql_store_result()``), it is complicated by SSCursor (which uses ``mysql_use_result()``; with the latter you must ensure all the rows have been read before another query can be executed. It is further complicated by the addition of transactions, since transactions start when a cursor execute a query, but end when ``COMMIT`` or ``ROLLBACK`` is executed by the Connection object. Two threads simply cannot share a connection while a transaction is in progress, in addition to not being able to share it during query execution. This excessively complicated the code to the point where it just isn't worth it.

The general upshot of this is: Don't share connections between threads. It's really not worth your effort or mine, and in the end, will probably hurt performance, since the MySQL server runs a separate thread for each connection. You can certainly do things like cache connections in a pool, and give those connections to one thread at a time. If you let two threads use a connection simultaneously, the MySQL client library will probably upchuck and die. You have been warned.

vasilenko ★★
()

Проблема в MySQLdb. Используемый интерфейс не позволяет обращаться к одному соединению больше, чем из одного треда. Очевидное решение - connection pooling.

shylent
()
Ответ на: комментарий от shylent

> Очевидное решение - connection pooling.

Вкратце - это что-то типа создания многозвенного приложения?

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Это совершенно перпендикулярно многозвенному приложению. Создаёшь несколько (пул) соединений, каждая нить хватает одно, работает что надо, потом освобождает.

fat-II
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.