SQL事务和表SELECT LOCK澄清

时间:2014-02-20 13:33:00

标签: php mysql database postgresql transactions

我对在线交易有疑问,并希望通过SELECTUPDATE查询澄清以下问题。

我将使用以下示例向您解释此事。

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中再次检查余额。

  1. 使用默认的Mysql事务,首先是值 和第二次平衡结果?默认情况下,使用“SELECT ... LOCK IN SHARE MODE” or “SELECT ... FOR UPDATE”功能的Mysql也可以 我们必须在查询中使用它们。
  2. 如果我们需要为上述两次余额检查查询返回800美元 等待事务提交我们可以使用哪种方法例如: “SELECT ... LOCK IN SHARE MODE” or “SELECT ... FOR UPDATE

  3. 你也知道Mysql和Post greSql是否处理了 如上所述,交易有何不同?

1 个答案:

答案 0 :(得分:3)

在MySQL(使用InnoDB)和PostgreSQL中,使用READ COMMITTED或SERIALIZABLE隔离模式,在步骤2和步骤3中的余额将相同。只有在事务提交后才能看到更改。

使用MyISAM的MySQL可能会有所不同,但如果您关心数据的正确性或一致性,则不应使用它。

除非您特别要求,否则MySQL和PostgreSQL都不会执行FOR SHAREFOR UPDATE

PostgreSQL和MySQL(InnoDB)在READ COMMITTED模式下的行为应该相似。有关PostgreSQL行为的详细信息,请参阅manual on transaction isolation

如果您想要获得800两次读取,如上所述,您必须做两件事:

  • SELECT ... FOR UPDATE交易记录和INSERT余额之前,更新交易必须UPDATE用户的余额记录;以及

  • 读取事务("其他脚本")每当读取它时都必须SELECT ... FOR SHARE余额,因此只要其他人正在更新它,它就会等待,而不是只读取未更改的版本