锁定表可防止其他数据库用户影响您锁定的行/表。但锁,它们自己,不会确保你的逻辑出来在一致的状态。
想想银行系统。当您在线支付帐单时,至少有两个受到交易影响的帐户:您的帐户,从中取款。和接收者的帐户,钱转入。和银行的帐户,他们将乐意存入交易收取的所有服务费。鉴于(大家都知道这些日子)银行是非常愚蠢的,让我们说他们的系统工作如下:
$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;
$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance + $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance
现在,没有锁和没有交易,这个系统容易受到各种竞争条件,其中最大的是多个付款正在您的帐户或接收方的帐户并行执行。虽然你的代码有你的余额检索,并正在做的huge_overdraft_fees()和whatnot,完全可能的是,一些其他付款将运行相同类型的代码并行。他们将检索您的余额(比如说,100美元),做交易(拿出你支付的20美元,以及30美元他们拧紧你),现在两个代码路径有两个不同的余额:$ 80和$ 70。根据最后一次结算,您最终会得到帐户中的这两个余额,而不是您应该结束的$ 50($ 100 – $ 20 – $ 30)。在这种情况下,“银行错误对您有利”。
现在,让我们说你使用锁。您的帐单付款($ 20)先到达管道,因此它赢得并锁定您的帐户记录。现在你有独家使用,可以从余额中扣除20美元,并将新的余额写回来,在和平…和你的帐户最终以$ 80的预期。但是… uhoh …你尝试去更新接收者的帐户,并且它被锁定,锁定时间超过代码允许,超时你的事务…我们正在处理愚蠢的银行,所以,而不是有正确的错误处理,代码只是拉出一个exit(),你的$ 20消失了一个电子。现在你20美元,你还欠20美元接收器,你的电话被收回。
所以…输入事务。你开始一个交易,你借记你的帐户$ 20,你尝试信用接收器与$ 20 …和一些东西爆炸了。但是这次,代替exit(),代码可以只做回滚,poof,你的20美元神奇地添加到您的帐户。
最后,它归结为:
锁让任何人都不会干扰你正在处理的任何数据库记录。事务保持任何“以后的”错误干扰“早”的事情你做了。不能单独保证事情工作到最后确定。但在一起,他们。
在明天的课:死亡的快乐。