Sobes.tech
Назад к вопросам
Junior — Middle
62

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

Компании, где спрашивали
Баланс-ПлатформаБаланс-Платформа

Ответ от нейросети

sobes.tech AI

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

Примерный подход:

  1. В базе данных создается запись заявки с флагом "неотправлено".
  2. В транзакции:
    • Создается запись заявки.
    • Отправляется сообщение в очередь (например, RabbitMQ, Kafka).
    • Если отправка успешна, обновляется флаг заявки на "отправлено".
  3. Если отправка сообщения не удалась, транзакция откатывается, чтобы заявка не осталась в базе без сообщения.

Если очередь поддерживает подтверждения (ack), нужно дождаться подтверждения доставки сообщения.

Пример на Python с использованием библиотеки pika для RabbitMQ и SQLAlchemy:

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import pika

Base = declarative_base()

class Request(Base):
    __tablename__ = 'requests'
    id = Column(Integer, primary_key=True)
    data = Column(String)
    sent = Column(Boolean, default=False)

engine = create_engine('sqlite:///requests.db')
Session = sessionmaker(bind=engine)

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='task_queue', durable=True)

session = Session()
try:
    new_request = Request(data='some data')
    session.add(new_request)
    session.flush()  # получить id

    message = new_request.data
    channel.basic_publish(
        exchange='',
        routing_key='task_queue',
        body=message,
        properties=pika.BasicProperties(delivery_mode=2)  # persistent message
    )

    new_request.sent = True
    session.commit()
except Exception as e:
    session.rollback()
    print('Ошибка при отправке заявки:', e)
finally:
    session.close()
    connection.close()

Таким образом, либо заявка и сообщение создаются вместе, либо не создаются вовсе, что обеспечивает надежность.