Многопоточность для запросов в SQL База данных - PullRequest
2 голосов
/ 02 мая 2020

Предположим, у меня есть база данных, например, для мессенджера. Мое приложение собирает сообщения и сохраняет их в моей базе данных. Неважно, какой это тип базы данных (я не хочу знать, как она обычно воплощается, и поддерживает ли моя база данных это, и есть ли другие базы данных, которые делают, если это не так), но в моем случае это PostgreSQL. Я также использую python psychopg2 адаптер. На самом деле я хочу управлять всеми запросами, чтобы они не прерывали друг друга.

Давайте проясним, что я хочу. Предположим, у нас есть два потока, по-видимому, два клиента, , которые работают в разных потоках , и они загружают сообщения из базы данных. Клиент 1 работает:

SELECT * FROM messages WHERE user_id = client1_id;

Чтобы выбрать все сообщения, которые он написал, из базы данных, а затем пытается извлечь данные, но вместо этого, что это становится, я думаю , все сообщения от Client2. Что происходит сейчас, это:

# in thread 1:

  cursor.execute('SELECT * FROM messages WHERE user_id = %s;', client1_id)

# in thread 2

  cursor.execute('SELECT * FROM messages WHERE user_id = %s;', client2_id)   << this is the last SELECT

# then again in thread 1

  cursor.fetchall()                                                          << fetching data from the last select

# and then in thread 2

  cursor.fetchall()

Что я думаю, что произойдет , если Client1 будет извлекать данные из последнего выбора, в данном случае это данные из Client2, и Вот на этот вопрос я пытаюсь найти ответ.


ВОПРОС

Как я могу читать и записывать данные из моей базы данных в разных потоки, так что каждый клиент выполняет свои запросы отдельно от других клиентов?


Как уже упоминалось здесь , множественные соединения не являются хорошим решением для меня, и я думаю, что нет смысла буферизовать все запросы и выполнять их последовательно, когда у вас есть, например, 10000 пользователей. Итак, какую архитектуру я должен использовать для этого случая? Спасибо в andvance.

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

Для современных баз данных каждый запрос будет выполняться в отдельном «пространстве». Это означает, что эти два запроса могут возвращать разные наборы результатов.

Страница википедии Многоуровневый контроль параллелизма - хорошее чтение.

Кроме того, помните, что при получении данных из базы данных вы получаете только копию данных; Вы не контролируете это в своем приложении. В тот момент, когда вы извлекаете эти данные из базы данных, они уже могут быть устаревшими , так как некоторые другие потоки или приложения уже могли их изменить.

Кроме того, я бы рекомендовал это в сильно многопоточных Приложение вы должны рассмотреть "Шаблон номера версии", чтобы обнаружить и контролировать много пользователей, обновляющих одни и те же данные. В противном случае неправильно разработанное приложение может привести к непреднамеренному повреждению данных.

1 голос
/ 02 мая 2020


Привет,

В основном, когда вы открываете соединение в любом, это хороший способ закрыть его, а затем создать новое соединение. В приведенном выше коде вы выполняете два запроса и выбираете после второго потока. Теперь вы получите результат для второго потока. Правильный подход состоит в том, чтобы создать соединение, получить результат и закрыть соединение, когда ваша операция завершена, а затем открыть новое соединение, так же как выполнить операцию и закрыть ее. Такой подход очень хорош для использования на любом языке программирования. Ниже приведен пример кода,

# in thread 1:

   cursor.execute('SELECT * FROM messages WHERE user_id = %s;', client1_id)

   cursor.fetchall()   
   con.close()   

# in thread 2

   cursor.execute('SELECT * FROM messages WHERE user_id = %s;', client2_id)   

   cursor.fetchall()
   con.close()

Дайте мне знать, если вам неясно

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...