如何在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
相关产品推荐
相关产品推荐

