gpt4 book ai didi

mysql - 拍卖/银行类应用程序中的乐观或悲观锁定 (Rails/MySQL)

转载 作者:可可西里 更新时间:2023-11-01 08:21:12 26 4
gpt4 key购买 nike

我正在使用 Rails 3.1 和 MySQL 5.1 设计一个类似拍卖的 Web 应用程序。用户会有账户余额,因此重要的是,如果有人没有足够的资金就不要竞标拍卖品。

显然,我会将拍卖的“获胜”打包到交易中,如下所示:

交易 1:

ActiveRecord::Base.transaction do
a = Account.where(:id=>session[:user_id]).first
# now comes a long part of code with various calculations and other table updates, i.e. time pases
a.balance -= the_price_of_the_item
a.save!
end

顺便说一下,我目前正在使用乐观锁定,因此我所有的表都有 lock_version 列。

在执行此类交易时,用户可以通过另一个输入进行其他出价,因此每当他们出价时,一段代码会检查当前可用余额是否足够

这里还是一样:

交易 2:

ActiveRecord::Base.transaction do
a = Account.where(:id=>session[:user_id]).first
raise ActiveRecord::Rollback if a.balance < the_price_of_the_bid + Bids.get_total_bid_value_for_user(session[:user_id])
# now process the bid saving
end

显然,我需要确保这两个交易不重叠,否则交易 2 可能正在读取余额,而交易 1 正在处理中,我最终会出现负账户余额(出价被保存,之后事务 1 提交,然后用户可能用他不再拥有的资金出价)。

需要注意的是,事务 2 没有对帐户进行任何更改,它只是读取帐户。我想这归结为一个问题:如何在运行事务 1 时防止对选定的 SELECT 语句进行任何读取。

如何让事务 2 等待事务 1 完成?是否可以使用乐观锁定和可用的 MySQL 事务隔离级别之一,或者我是否需要在此处使用悲观锁定?如果悲观锁定是唯一的答案会添加 a.锁!在两次交易中分别读取账户记录后就足够了吗?

当然是设计标准

  • 我正在寻找性能最好的解决方案,即使它意味着更多编码。
  • 数据一致性至关重要

最佳答案

现在我花了将近 10 个小时不停地阅读各种帖子和文档,并使用 Rails 控制台反复试验,我想总结一下我的发现:

乐观锁:对解决我的要求没有用,只有当我真正保存了账户余额记录时,锁才会起作用。但是出价不会更新账户记录,所以它不会触发乐观锁定,除非我在账户记录中维护一个字段来跟踪我当前为所有公开出价 promise 的资金,因此将在出价时更新账户记录(我不想这样做,因为每当保存出价时都需要另一个数据库更新)。

所以我只剩下悲观锁定了。为了简单起见,我决定锁定用户记录,因此我的事务 1 的代码更改为:

交易 1:

ActiveRecord::Base.transaction do     
u = User.find(session[:user_id],:lock=>true)
a = Account.where(:id=>session[:user_id]).first
a.balance -= the_price_of_the_item
... some more code here ...
a.save!
end

和事务 2:

ActiveRecord::Base.transaction do
u = User.find(session[:user_id],:lock=>true)
raise ActiveRecord::Rollback if a.balance < the_price_of_the_bid + Bids.get_total_bid_value_for_user(session[:user_id])
# now process the bid saving
....
end

此外,我决定将 MySQL 事务隔离级别设置为 SERIALIZABLE。

关于mysql - 拍卖/银行类应用程序中的乐观或悲观锁定 (Rails/MySQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8676128/

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