免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2375 | 回复: 0
打印 上一主题 下一主题

Using optimistic locking in PostgreSQL [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-22 19:16 |只看该作者 |倒序浏览
[注] 取材自《PostgreSQL 9 Administration Cookbook》
本书电子版可以到以下网址下载:
http://www.boobooke.com/bbs/thread-59726-1-1.html

首先看如下一个场景:
BEGIN;
SELECT * FROM ACCOUNTS WHERE HOLDER_NAME ='BOB' FOR UPDATE;
<do some calculations here>
UPDATE ACCOUNTS SET BALANCE = 42.00 WHERE HOLDER_NAME ='BOB';
COMMIT;

在上面这个场景中,用户在做UPDATE之前先锁住需要被UPDATE的记录,进行完部分运算操作后再进行更新的操作,以便确保在更新前这部分记录不会被其他用户修改。
对于这种场景可以在应用设计时考虑使用乐观锁来获得整体性能的提升,乐观锁假设大多数情况下用户将要更新的记录在一定时间段内不会被其他用户更新。
做法举例如下:
BEGIN;
SELECT A.*, (A.*::text) AS OLDACCINFO
  FROM ACCOUNTS A WHERE HOLDER_NAME ='BOB';
<do some calculations here><运算过程>
UPDATE ACCOUNTS SET BALANCE = 42.00
WHERE HOLDER_NAME ='BOB'
AND  (A.*::text) = <OLDACCINFO from select above>;
COMMIT;
在上面这个场景中,用户首先将需要被更新的记录取出,运算完后,更新时与前面取出的记录进行比较。如果一致则更新成功。
【这种场景也存在一定的局限性,最好在设计时每个表都有PK,并且PK不会被更新。否则存在安全隐患】
使用场景扩展-1:
SELECT A.*, (A.*::text) AS OLDACCINFO
  FROM ACCOUNTS A WHERE HOLDER_NAME ='BOB';
这条SQL可以根据用户的需求,进行一定的调整。比如只要确保某些字段没有被其他用户更新就认为接下来的更新是有效的。如last_charge(标识最后一次更新的时间),balance(用户帐户余额) 这两个字段没有被其他用户更新的话就认为下一次更新是有效的。而其他字段如EMAIL这个不太重要的字段允许在运算过程中被更新.

使用场景扩展-2:
CREATE OR REPLACE FUNCTION consume_balance (
   i_username text, i_amount numeric(10,2), max_credit numeric(10,2),
   OUT success boolean, OUT remaining_balance numeric(10,2)) AS
$$
BEGIN
    UPDATE accounts SET balance = balance - i_amount
     WHERE username = i_username
       AND balance - i_amount > - max_credit
RETURNING balance
      INTO remaining_balance;
   IF NOT FOUND THEN
       success := FALSE;
       SELECT balance
         FROM accounts
        WHERE username = i_username
         INTO remaining_balance;
   ELSE
       success := TRUE;
   END IF;
END;
$$ LANGUAGE plpgsql;

以上场景是函数中使用乐观锁的示例,
在函数中使用的好处是简化交互过程,在同一个SESSION中复用执行计划等.
调用 :
SELECT * FROM consume_balance ('bob', 7, 0);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP