防止数据完整性的SQL事务中的竞争条件

时间:2016-10-21 09:40:32

标签: sql postgresql concurrency race-condition

示例情况

我有一个客户订阅的银行应用程序,帮助收集捐款。

CREATE TABLE clients (
   id BIGINT,
   balance BIGINT
    );

CREATE TABLE transactions(
  tx_id BIGSERIAL,
   amount BIGINT,
   client_id BIGINT,
   customer_id BIGINT
   mode VARCHAR (20)
 );

我的客户有一个收集这笔资金的媒介,他拥有庞大的客户群,每秒贡献一次,比如每秒5笔捐款。

这5个实例同时执行的SQL事务代码:

BEGIN;
INSERT INTO transactions (amount, client_id, customer_id mode)
    VALUES (10.00, 3345, 454, "web");

SAVEPOINT save_tx_cs454;

UPDATE clients SET balance = balance + 10
    WHERE id = 3345 RETURNING balance;

COMMIT; 

问题

  • 如何构建代码以确保客户端UPDATE balance正确完成。 (例如,在这些报表末尾的前期余额为500美元,可用余额为550美元)
  • 我可以使用LOCKS,因为ROW LEVEL LOCKING可用,我该怎么做
  • 我还有其他方法可以实现这一点,还是有更好的方法来优化它。

注意:带有备注的代码示例可能更适合回答。

1 个答案:

答案 0 :(得分:4)

您的交易将自动执行正确的操作。

如果所有5个事务都尝试更新$srchDate = date_format(date_create_from_format('d/m/Y', $srchDate), 'Y/m/d');中的相同记录,则每个事务都尝试对该行进行clients锁定。碰巧先到的交易将获得锁定,而其他交易必须等到锁定被释放,这是在交易结束时。

因此,ROW EXCLUSIVE上的更新将被序列化,最终结果将保证为550.