gpt4 book ai didi

python - 跨函数共享 MySQLdb 事务

转载 作者:行者123 更新时间:2023-11-28 19:25:11 25 4
gpt4 key购买 nike

我正在使用 MySQLdb 通过 python 连接到 MySQL。我的表都是 InnoDB 并且我正在使用事务。

我正在努力想出一种跨职能“共享”交易的方法。考虑以下伪代码:

def foo():
db = connect()
cur = db.cursor()
try:
cur.execute(...)
conn.commit()
except:
conn.rollback()

def bar():
db = connect()
cur = db.cursor()
try:
cur.execute(...)
foo() # note this call
conn.commit()
except:
conn.rollback()

在我的代码中的某些点,我需要调用 foo(),而在某些点我需要调用 bar()。这里的最佳做法是什么?如果在 bar() 外部调用但不在 bar() 内部调用,我如何将对 foo() 的调用告诉 commit() ?如果有多个线程调用 foo()bar() 并且调用 connect() 不返回,这显然会更复杂相同的连接对象。

更新

我找到了适合我的解决方案。我包装了 connect() 以在调用时增加一个值。调用 commit() 会减少该值。如果 commit() 被调用并且该计数器 > 0,则不会发生提交并且该值会递减。因此你得到这个:

def foo():
db = connect() # internal counter = 1
...
db.commit() # internal counter = 0, so commit


def bar():
db = connect() # internal counter = 1
...
foo() # internal counter goes to 2, then to 1 when commit() is called, so no commit happens
db.commit() # internal counter = 0, so commit

最佳答案

在这种情况下,您可以利用 Python 的默认函数参数:

def foo(cur=None):
inside_larger_transaction = False
if cursor is None:
db = connect()
cur = db.cursor()
inside_larger_transaction = True
try:
cur.execute(...)
if not inside_larger_transaction:
conn.commit()
except:

conn.rollback()

因此,如果 bar 正在调用 foo,它只是将光标对象作为参数传入。

并不是说我认为为每个小函数创建不同的游标对象没有多大意义——你应该将几个函数写成对象的方法,并具有游标属性——或者总是显式地传递游标(在在这种情况下,使用另一个命名参数来指示当前函数是否是主要事务的一部分)

另一种选择是创建一个 context-manager类来进行提交,并将所有事务封装在其中 - 因此,您的任何函数都不应该执行事务提交 - 您将同时保留 transaction.commit 和 transaction.rollback 调用此对象的 __exit__ 方法.

class Transaction(object):
def __enter__(self):
self.db = connect()
cursor = self.db.cursor()
return cursor
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is None:
self.db.commit()
else:
self.db.rollback()

然后像这样使用它:

def foo(cursor):
...

def foo(cur):
cur.execute(...)


def bar(cur):
cur.execute(...)
foo(cur)

with Transaction() as cursor:
foo(cursor)


with Transaction() as cursor:
bar(cursor)

关于python - 跨函数共享 MySQLdb 事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14967880/

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