gpt4 book ai didi

python - 如何在数据库中使 Tornado 请求原子化

转载 作者:太空宇宙 更新时间:2023-11-03 14:48:01 26 4
gpt4 key购买 nike

我有一个用 Tornado 异步框架编写的 python 应用程序。当一个 HTTP 请求进来时,这个方法被调用:

@classmethod
def my_method(cls, my_arg1):

# Do some Database Transaction #1
x = get_val_from_db_table1(id=1, 'x')
y = get_val_from_db_table2(id=7, 'y')
x += x + (2 * y)

# Do some Database Transaction #2
set_val_in_db_table1(id=1, 'x', x)

return True

这三个数据库操作是相互关联的。这是一个并发应用程序,因此多个此类 HTTP 调用可以同时发生并访问同一个数据库。

出于数据完整性的目的,重要的是调用此方法中的三个数据库操作时没有其他进程读取或写入中间的那些数据库行。

如何确保此方法具有数据库原子性? Tornado 有这个装饰器吗?

最佳答案

同步数据库访问

你还没有说明你是如何访问你的数据库的。如果(这很可能)您在 get_val_from_db_table1 和 friend (例如 pymysql )中有同步数据库访问并且 my_method 正在阻塞(不将控制返回到 IO 循环)然后你阻止你的服务器(这对你的服务器的性能和响应能力有影响)但有效地序列化你的客户端并且一次只有一个可以执行 my_method 。所以在数据一致性方面你不需要做任何事情,但通常这是一个糟糕的设计。您可以在短期内使用@xyres 的解决方案来解决这两个问题(因为 Tornado 的大部分功能 isn't thread-safe 需要牢记线程安全问题)。

异步数据库访问

如果您在 get_val_from_db_table1 和 friend (例如 tornado-mysql )中有异步数据库访问,那么您可以使用 tornado.locks.Lock .这是一个例子:

from tornado import web, gen, locks, ioloop


_lock = locks.Lock()

def synchronised(coro):
async def wrapper(*args, **kwargs):
async with _lock:
return await coro(*args, **kwargs)

return wrapper


class MainHandler(web.RequestHandler):

async def get(self):
result = await self.my_method('foo')
self.write(result)

@classmethod
@synchronised
async def my_method(cls, arg):
# db access
await gen.sleep(0.5)
return 'data set for {}'.format(arg)


if __name__ == '__main__':
app = web.Application([('/', MainHandler)])
app.listen(8080)
ioloop.IOLoop.current().start()

注意上面说的是正常的单进程 Tornado 应用。如果你使用 tornado.process.fork_processes,那么你只能使用 multiprocessing.Lock .

关于python - 如何在数据库中使 Tornado 请求原子化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47946202/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com