假设我有一个储蓄账户和一个支票账户。我的储蓄账户余额是150美元。我正在尝试将100美元从我的储蓄帐户转移到支票帐户,也将100美元从我的储蓄帐户转移到我朋友的帐户。
将100美元从我的储蓄帐户转移到我的支票帐户的步骤:
1.1。读(current_saving_balance)
1.2。将saving_balance减少100
1.3。将100添加到我的checking_balance
将100美元从我的储蓄帐户转移到朋友帐户的步骤:
2.1。读(current_saving_balance)
2.2。将saving_balance减少100
2.3。将100添加到我朋友的帐户余额
我想同时执行这些事务。如果他们都在开始时读取了saving_balance,那么两者都可以将saving_balance减少100 $,但是,其中只有一个应该能够成功。如何处理银行系统。
答案 0 :(得分:0)
不需要可序列化的隔离级别(但是,从数据库系统到数据库系统,确切的loggin语义是非常不同的。)
确保执行更新语句时,它仍然具有与读取时相同的值,否则重新执行
没有必要明确地读取数据,一个简单的更新语句就足够了(但是需要有一个逻辑来检查帐户中是否有足够的资金,这可以通过触发来实现。)
答案 1 :(得分:0)
您有实际交易(1.转账100美元.2。转账100美元给朋友) 而你正在尝试的是在单一的技术交易中(开始; ......;提交)。我认为这是错误的方法。您的代码必须反映实际交易,即 开始; ...... 1.转账100美元。 ;承诺; 开始; ...... 2.将100美元转给朋友)。 ;承诺; 有一些数据库功能,它会在每次交易前检查余额,并决定是否保存。
答案 2 :(得分:0)
以下是如何在tSQL中执行此操作,您的数据库的语法可能会有所不同。
BEGIN TRAN
UPDATE accounts
SET balance = balance-100
WHERE account='1'
UPDATE accounts
SET balance = balance + 100
WHERE account='2'
COMMIT TRAN
我建议您阅读this article以更多地了解数据库事务。
忽略评论中发生的整个可序列化隔离对话。它并没有真正解决你所描述的问题。