You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Telethon库收到指定聊天新消息后立即断开客户端并解决数据库锁问题

Telethon事件回调中断开连接报sqlite数据库锁的问题排查与解决

错误原因

  • 直接在事件回调内执行await client.disconnect():Telethon处理消息事件的全程会持有会话sqlite文件的读写锁,回调还没执行完成就强制断开连接,会导致事务未正常结束、锁未释放,触发sqlite3.OperationalError: database is locked报错。
  • 重复调用连接方法:代码中同时调用await client.connect()和await client.start(),client.start()内部已经封装了完整的连接鉴权逻辑,重复触发连接操作会导致会话文件被多次抢占,进一步提高锁冲突概率。

正确实现方案

方案1(推荐:无延时、逻辑安全)

通过异步事件标志位通知主逻辑断开,避免打断回调内的数据库操作:

import asyncio
from telethon import TelegramClient, events

bot_id = "chat id of telegram bot"
# 替换为你自己的api_id、api_hash、会话文件名
client = TelegramClient('your_session_name', api_id=123456, api_hash='your_api_hash')

# 定义断开连接的标志位
disconnect_signal = asyncio.Event()

@client.on(events.NewMessage(chats=bot_id))
async def imp_msg(event):
    await client.send_message(123456, event.message)
    # 仅标记需要断开,不直接执行断开操作
    disconnect_signal.set()

async def main():
    async with client:
        # 等待断开标志触发
        await disconnect_signal.wait()
        # 所有回调执行完成后再执行断开
        await client.disconnect()

if __name__ == "__main__":
    asyncio.run(main())

方案2(快速适配原有写法)

去掉重复的client.connect()调用,断开前增加短延时确保数据库操作完成:

bot_id = "chat id of telegram bot"

@client.on(events.NewMessage(chats=bot_id))
async def imp_msg(event):
    await client.send_message(123456, event.message)
    # 延时100毫秒,等待当前事件关联的数据库事务完成
    await asyncio.sleep(0.1)
    await client.disconnect()

# 去掉多余的await client.connect(),仅保留start
await client.start()
await client.run_until_disconnected()

内容的提问来源于stack exchange,提问作者abhishek surela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:24:04