我对在线交易有疑问,并希望通过SELECT
和UPDATE
查询澄清以下问题。
我将使用以下示例向您解释此事。
X正在进行在线交易。他的帐户余额为$1000
。他将购买200美元的商品,之后他的帐户余额应为$800
。那样就好;现在让我进一步详细说明
Begin DB transaction.
Step 1: account balance is $1000
{Select the balance from a different script}
Step 2: Buy something for $200
{Select the balance from another script}
Step 3: Remaining balance $800
Commit DB transaction
正如您在第1步和第3步之间看到的那样,余额已由交易外的其他查询检查,另一个脚本在步骤2和3中再次检查余额。
“SELECT
... LOCK IN SHARE MODE” or “SELECT ... FOR UPDATE”
功能的Mysql也可以
我们必须在查询中使用它们。如果我们需要为上述两次余额检查查询返回800美元
等待事务提交我们可以使用哪种方法例如:
“SELECT ... LOCK IN SHARE MODE” or “SELECT ... FOR UPDATE
”
你也知道Mysql和Post greSql是否处理了 如上所述,交易有何不同?
答案 0 :(得分:3)
在MySQL(使用InnoDB)和PostgreSQL中,使用READ COMMITTED或SERIALIZABLE隔离模式,在步骤2和步骤3中的余额将相同。只有在事务提交后才能看到更改。
使用MyISAM的MySQL可能会有所不同,但如果您关心数据的正确性或一致性,则不应使用它。
除非您特别要求,否则MySQL和PostgreSQL都不会执行FOR SHARE
或FOR UPDATE
。
PostgreSQL和MySQL(InnoDB)在READ COMMITTED模式下的行为应该相似。有关PostgreSQL行为的详细信息,请参阅manual on transaction isolation。
如果您想要获得800两次读取,如上所述,您必须做两件事:
在SELECT ... FOR UPDATE
交易记录和INSERT
余额之前,更新交易必须UPDATE
用户的余额记录;以及
读取事务("其他脚本")每当读取它时都必须SELECT ... FOR SHARE
余额,因此只要其他人正在更新它,它就会等待,而不是只读取未更改的版本