Flask-SQLAlchemy with_for_update()行锁定

Dao*_*eng 4 python mysql locking flask flask-sqlalchemy

我有一个名为'User'的模型,'User'有'Money'.
有一种情况是多个会话可以读取模型"用户"并同时更新"钱".

会话1应在会话1成功更新后读取"钱"值.
我在更新时试图锁定"用户"行.
这是我的代码.

user = User.query.with_for_update().filter_by(id=userid).first()
print('000000')
before_money = user.money
print('111111')
time.sleep(1)
user.money -= 0.1
print('User:' + str(user.id) + '***' + str(before_money) + '-' + str(0.1) + ' = ' + str(user.money))
time.sleep(1)
db.session.commit()
print('22222')
Run Code Online (Sandbox Code Playgroud)

我打开了两个会话来同时运行这段代码,输出

000000
111111
User:1***125.3-0.1 = 125.2
000000
111111
22222
User:1***125.3-0.1 = 125.2
22222
Run Code Online (Sandbox Code Playgroud)

第2节没有读取更新的值.

我真的想知道问题出在哪里.

Dao*_*eng 9

经过一整天的努力,我发现了问题所在.

user = User.query.with_for_update().filter_by(id=userid).first()
Run Code Online (Sandbox Code Playgroud)

应该

result = db.session.query(User.money).with_for_update().filter_by(id=userid).first()
money = result[0]
user.money = money - 0.1
Run Code Online (Sandbox Code Playgroud)

是的,这么简单但很烦人

  • 不是“烦人”,只是“逻辑”:查询是一个函数,在它上面询问“更新”会感觉很奇怪......在**结果**(实际查询)上执行它更有意义. 请注意,我认为您也可以在过滤器之后添加它(因为这些函数返回查询 (2认同)
  • 你从哪里得到 user.money = Money - 0.1 中的“user” (2认同)

小智 7

你只需要声明你想要锁定的内容:

user = User.query.with_for_update(of=User).filter_by(id=userid).first()
user.money -= 0.1
Run Code Online (Sandbox Code Playgroud)