为什么 aiomysql 即使在使用上下文管理器时也会锁定 table?
Why aiomysql locks the table even when using context manager?
我注意到即使我在 "with" 上下文管理器中执行 sql 语句,在请求完成后,查询的 table 仍然被锁定,我无法执行 "truncate" 直到我停止事件循环。
这是我的代码示例:
import logging
import asyncio
import aiomysql
from aiohttp import web
from aiomysql.cursors import DictCursor
logging.basicConfig(level=logging.DEBUG)
async def index(request):
async with request.app["mysql"].acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("SELECT * FROM my_table")
lines = await cur.fetchall()
return web.Response(text='Hello Aiohttp!')
async def get_mysql_pool(loop):
pool = await aiomysql.create_pool(
host="localhost",
user="test",
password="test",
db="test",
cursorclass=DictCursor,
loop=loop
)
return pool
if __name__ == "__main__":
loop = asyncio.get_event_loop()
mysql = loop.run_until_complete(get_mysql_pool(loop))
app = web.Application(loop=loop, debug=True)
app["mysql"] = mysql
app.router.add_get("/", index)
web.run_app(app)
执行 curl 'http://localhost:8080/' 后,我正在使用 mysql cli 连接到 mysql 服务器并尝试执行 "truncate my_table" - 它不会完成直到我停止 aiohttp。如何改变这种行为?
由于默认情况下连接未处于 autocommit 模式,因此持有锁。添加 autocommit=True
应该可以解决问题。
pool = await aiomysql.create_pool(
host="localhost",
user="test",
password="test",
db="test",
autocommit=True,
cursorclass=DictCursor,
loop=loop)
或者可以通过显式命令释放交易:
await cur.execute("COMMIT;")
此处上下文管理器的主要目的是关闭游标,而不是提交事务。
aiomysql 具有 SQLAlchemy.core 扩展,支持事务的上下文管理器,请参见此处的示例:
我注意到即使我在 "with" 上下文管理器中执行 sql 语句,在请求完成后,查询的 table 仍然被锁定,我无法执行 "truncate" 直到我停止事件循环。
这是我的代码示例:
import logging
import asyncio
import aiomysql
from aiohttp import web
from aiomysql.cursors import DictCursor
logging.basicConfig(level=logging.DEBUG)
async def index(request):
async with request.app["mysql"].acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("SELECT * FROM my_table")
lines = await cur.fetchall()
return web.Response(text='Hello Aiohttp!')
async def get_mysql_pool(loop):
pool = await aiomysql.create_pool(
host="localhost",
user="test",
password="test",
db="test",
cursorclass=DictCursor,
loop=loop
)
return pool
if __name__ == "__main__":
loop = asyncio.get_event_loop()
mysql = loop.run_until_complete(get_mysql_pool(loop))
app = web.Application(loop=loop, debug=True)
app["mysql"] = mysql
app.router.add_get("/", index)
web.run_app(app)
执行 curl 'http://localhost:8080/' 后,我正在使用 mysql cli 连接到 mysql 服务器并尝试执行 "truncate my_table" - 它不会完成直到我停止 aiohttp。如何改变这种行为?
由于默认情况下连接未处于 autocommit 模式,因此持有锁。添加 autocommit=True
应该可以解决问题。
pool = await aiomysql.create_pool(
host="localhost",
user="test",
password="test",
db="test",
autocommit=True,
cursorclass=DictCursor,
loop=loop)
或者可以通过显式命令释放交易:
await cur.execute("COMMIT;")
此处上下文管理器的主要目的是关闭游标,而不是提交事务。
aiomysql 具有 SQLAlchemy.core 扩展,支持事务的上下文管理器,请参见此处的示例: