Почему при выполнении кода создается пять тикетов, вместо одного?

Почему код создает сразу 5 тикетов вместо 1? Как можно устранить эту проблему? <br/> <pre><code class="python">py
if selected_option == "1":
            c.execute(f"SELECT id_member FROM users WHERE id_member = {inter.author.id}")
            if c.fetchone() is not None:
                await inter.response.send_message("Вы уже создали тикет!", ephemeral=True)
                return
            else:
                overwrites = {
                    guild.default_role: disnake.PermissionOverwrite(view_channel=False, read_messages=False),
                    master_role: disnake.PermissionOverwrite(read_messages=True, send_messages=True),
                    admin_role: disnake.PermissionOverwrite(read_messages=True, send_messages=True),
                    support_role: disnake.PermissionOverwrite(read_messages=True, send_messages=True),
                    inter.author: disnake.PermissionOverwrite(read_messages=True, send_messages=True),
                    guild.me: disnake.PermissionOverwrite(read_messages=True)  # Разрешение на чтение для бота
                }
                view = disnake.ui.View()
                view.add_item(disnake.ui.Button(emoji="", label='Закрыть', style=disnake.ButtonStyle.grey))
                view.add_item(disnake.ui.Button(emoji="", label='Принять тикет', style=disnake.ButtonStyle.blurple))
                ticket_channel = await category.create_text_channel(name=f'ticket-{inter.author.name}', overwrites=overwrites)
                c.execute(f"INSERT INTO users VALUES ({inter.author.id}, {ticket_channel.id})")
                conn.commit()
                embed = disnake.Embed(description=f"**Тикет был создан пользователем {inter.author.mention}. Ожидайте ответа!**
  • 27 октября 2024 г. 12:02
Ответы на вопрос 2
Причина, по которой ваш код создает пять тикетов вместо одного, может быть связана с тем, как часто выполняется блок кода, который создает тикет. Наиболее вероятно, что событие, связанное с вашим `selected_option`, вызывается несколько раз подряд. Это может происходить по следующим причинам:

1. **Событие вызывается несколько раз**: Если у вас есть механизм, который запускает этот код в ответ на одно и то же событие несколько раз, это может привести к созданию нескольких тикетов. Например, несколько нажатий кнопок или повторная отправка команды.

2. **Отсутствие механизма защиты**: Убедитесь, что проверка условия (например, `if c.fetchone() is not None`) выполняется до создания нового тикета и что запрос к базе данных работает корректно. Если запрос выполняется неправильно, код продолжит выполнение и создаст новые тикеты.

Чтобы решить проблему, можно предпринять следующие шаги:

### Потенциальные решения:

1. **Добавьте блокировку события**: Сделайте так, чтобы внутри этого блока кода был установлен флаг, запрещающий его повторное выполнение до завершения текущего выполнения.

```python
if selected_option == "1":
    c.execute(f"SELECT id_member FROM users WHERE id_member = {inter.author.id}")
    if c.fetchone() is not None:
        await inter.response.send_message("Вы уже создали тикет!", ephemeral=True)
        return
    else:
        # Установите флаг создание тикета
        inter.author.ticket_creation_in_progress = True
        try:
            # Остальная часть кода создания тикета...
        finally:
            # Сброс флага после завершения выполнения
            inter.author.ticket_creation_in_progress = False
```

2. **Добавьте ограничение по времени**: Установите временное ограничение, в течение которого создание нового тикета невозможно.

3. **Используйте asyncio.Lock**: Для синхронизации. Если вы используете асинхронные функции, то можно применить `asyncio.Lock`, чтобы избежать конфликтов при создании тикета.

Вот пример использования `asyncio.Lock`:

```python
lock = asyncio.Lock()

async def create_ticket(inter):
    async with lock:
        # Весь код по созданию тикета
```

Таким образом, отправив несколько команд одновременно, они будут обрабатываться последовательно, и вы избежите создания нескольких тикетов. Убедитесь, что ваши асинхронные функции должным образом управляются и не вызываются слишком быстро друг за другом, если это неуместно.
Код который вы приложили создаёт 1 канал и отправляет 1 ответ и 2 сообщения. 
Никаких пяти тикетов в нём нет.

Разбивайте код при помощи функций на понятные логические единицы и тестируйте их.
Похожие вопросы