在sql数据库中处理并发更新的常见方法是什么?
create table credits ( int id,int creds,int user_id );
意图是为用户存储某种类型的信用,例如像stackoverflow的声誉。
如何处理该表的并发更新?
几个选项:
> update credit set creds = 150 where userid = 1;
在这种情况下,应用程序检索当前值,计算新值(150)并执行更新。如果有人在同一时间做同样的事情,就会发生灾难。
我猜想包装当前值的retreival和更新在一个事务将解决,例如开始;从userid = 1的学分中选择凭证;应用程序逻辑来计算新值,更新学分集积分= 160,其中userid = 1;结束;在这种情况下,您可以检查新信用额度是否为0并且只要将其截断为0,如果否定的积分没有意义。
更新学分集合creds = creds – 150其中userid = 1;
这种情况不需要担心并发更新,因为数据库负责处理一致性问题,但是有一些缺陷使得信任会变得消极,这在某些应用程序中可能没有意义。
解决方法
使用交易:
BEGIN WORK; SELECT creds FROM credits WHERE userid = 1; -- do your work UPDATE credits SET creds = 150 WHERE userid = 1; COMMIT;
一些重要的注意事项:
>并非所有数据库类型都支持事务。特别是,MysqL的默认数据库类型MyISAM没有。如果你在MysqL上使用InnoDB。
>由于您无法控制的原因,交易可能会中止。如果发生这种情况,您的应用程序必须准备从BEGIN WORK开始重新开始。
>您需要将隔离级别设置为SERIALIZABLE,否则第一个select可以读取其他事务尚未提交的数据(事务不像编程语言中的互斥体)。如果并发持续的SERIALIZABLE事务,某些数据库将会发生错误,您必须重新启动事务。
>一些DBMS提供SELECT .. FOR UPDATE,这将锁定通过select进行撤销的行直到事务结束。