gpt4 book ai didi

python - 并发进程中的Django select_for_update函数

转载 作者:行者123 更新时间:2023-11-29 15:39:26 30 4
gpt4 key购买 nike

当我在多线程条件下测试update_or_create功能时,我发现结果不是我想要的,他们在MySQL中创建了不止一条记录。如代码所示,update_or_create使用select .. for update锁定MySQL中的行,那么MySQL中应该只有一条记录。我使用了 SQLAlchemy 并且 row sql 已经证明了这一点。

那么,Django 代码是错误的吗?

使用 Django 代码:

def get_or_create_ins():
p, created = OxalicAcid.objects.update_or_create(defaults={"formula": "20", "degree": "80"}, name="smart")

def run():
for i in range(10):
t = threading.Thread(target=get_or_create_ins, args=())
t.start()

if __name__ == "__main__":
# more than one record will be created
run()

使用 SQLAlchemy 代码:

@contextmanager
def transaction_atomic():
session = Session()
try:
yield session
session.commit()
except Exception as e:
session.rollback()
raise e


def get_result_with_update(session, name):
sql = text("""
select * from acid_oxalicacid where name = :name for update
""")
params = dict(name=name)
cursor = session.execute(sql, params)
result = cursor.fetchall()
return result


def get_result(session, name):
sql = text("""
select * from acid_oxalicacid where name = :name
""")
params = dict(name=name)
cursor = session.execute(sql, params)
result = cursor.fetchall()
return result


def create_data(session, name, degree, formula):
sql = text("""
insert into acid_oxalicacid (name, degree, formula) values (:name, :degree, :formula)
""")
params = dict(
name=name,
degree=degree,
formula=formula
)
session.execute(sql, params)


def get_or_create():
name = "smart"
degree = "50"
formula = "100"

with transaction_atomic() as session:
res = get_result_with_update(session, name)
if not res:
create_data(session, name, degree, formula)
res = get_result(session, name)
return res


if __name__ == "__main__":
# Only one record be created, that's correct
for i in range(10):
t = threading.Thread(target=get_or_create, args=())
t.start()

最佳答案

由于Django使用“读已提交”事务隔离级别,因此会出现多条记录,如果将其更改为“可重复读”,则数据库中将只有一条记录。

关于python - 并发进程中的Django select_for_update函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57834252/

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