• 数据库对并发的处理 乐观锁-悲观锁


    事务处理(多用户同时操作一条信息时是用-并发)

    在c/s或多层中,如果两个用户同时打开一条记录,修改后提交会产生更新冲突; 
    据说办法有二:1。打开同时锁定表的记录 2。浦获错误,撤消其中一个用户的修改,但是很少见到具体实现的代码;请大家告诉具体的代码怎么写: 
    1。打开时如何锁定一条记录? 
    2。如何扑获更新错误?在delphi中调试时会报“该记录读出后已经被再次修改”,而在运行时如何判定错误为更新冲突?因为更新时其他的错误如输入不合法等也可能报错,如何把更新冲突和其他的分开?

    =====================================================================

    http://hi.baidu.com/nboy/blog/item/8d61c93d8ab3dec19f3d6288.html

    首先,这个问题只有在特殊情况下才算是问题,大多数情况下可以不作考虑。

    然后,这是问题很难描述清楚,解决方案有多种,下面提供一种较方便易用的方式

    场景(问题)描述如下:

    0,用户A、B同时打开一个页面,页面显示,客户表T_CUSTOMER字段(C_NAME、C_AGE)

    姓名:张三,年龄:25

    1,A 将姓名“张三”改为“张三1”,然后保存

    2,B 将年龄“25”改为“30”,然后保存

    这样A的操作就被覆盖了,姓名又变回“张三”了,大家一般怎么处处这种情况?

    这里给出一个较易用的解决方案

    给表添加一字段:LAST_UPDATE,即最后更新时间

    回放场景

    0,用户A、B同时打开一页面,面页显示:

    姓名:张三,年龄:25,LAST_UPDATE:2008-10-17 13:45:00

    1,A 将姓名“张三”改为“张三1”,然后保存

    重点在这里:更新数据时WHERE条件里多一条件:AND LAST_UPDATE = '2008-10-17 13:45:00'

    更新成功,此时触发器会将当前时间“2008-10-17 13:46:00”赋值给LAST_UPDATE

    2,B 将将年龄“25”改为“30”,然后保存

    B更新数据时WHERE条件里也有这个条件:AND LAST_UPDATE = '2008-10-17 13:45:00',但此时LAST_UPDATE的值已经在A修改记录时变成2008-10-17 13:46:00

    下面要做的就是给出提示了:喔哟,此信息在你发呆这段时间已被人改过啦,所以你需要返工。

    触发器代码如下:
    ===================================================
    CREATE OR REPLACE TRIGGER T_CUSTOMER
    BEFORE UPDATE ON T_CUSTOMER
    FOR EACH ROW
    /*
    记录最后修改时间
    */
    BEGIN
    :NEW.LAST_UPDATE := SYSDATE;
    END;
    ===================================================

    如果触发器不熟悉或者只是不喜欢用触发器,完全可以修改记录时同时给LAST_UPDATE字段赋值,以此替代触发器的作用。

    ----------------------------------------------------------------------------------------------------------------

    http://blog.csdn.net/onemetre/archive/2010/11/06/5991658.aspx

    【并发操作】多用户并发操作的解决方案

    【问题】在以前的系统开发中,经常遇到一个同样问题,就是多个用户同时并发操作一条记录,这次在交易系统开发过程中,又出现了这样问题。比如交易商A提交单子,由审核人员B审核,此时A正在修改单位,B也正在查看这条记录,A先修改保存后B再审核保存,导致B审核通过的记录不是他所看到的。

    【分析】仔细考虑问题,大概分析了三个方法, 并确定了一个可行的方案,可能还有不完善的地方,但解决现有问题还是绰绰有余的。

    最先想的是在交易业务代码中用lock对修改方法加锁,运行时注入单例,并且对方法加同步锁,保证了业务数据的正确性, 但是效率低下,用户在使用中不方便,背离了系统可以并发操作的原则。

    然后考虑使用悲观锁,这次运行时注入原型,并发操作效率提高, 但是,在同步处理数据库表时又造成锁表,这样并发效率依旧很低。

    最后考虑乐观锁, 只是一种数据版本校验机制,它不做数据库层次上的锁定,需要在要并发操作的主表中加入一个"VERSION"字段或者“LASTUPDATETIME”,如果研究过oracle的SCN应该有异曲同工之妙,它的原理是这样:运行时注入原型,这时数据表并不锁住,只是每次update或insert时将VERSION更新, 当下次update,insert时,会校验VERSION,如果不一致,此时提示信息已经修改过了,并且在事务控制下rollback,这样,保证了数据的正确性,并且也不影响并发操作的效率。但是出现的问题是:如果A读了数据,未来及更新,B先更新了数据, 那么他将提交不上数据,因为VERSION已经失效,这样就造成了A重新读取数据,重新填写单据信息。 这也是乐观锁一个缺点,可以在更新前临时保存A填写的数据,再在跳转页中加载这些数据,保证了交易商不用麻烦再次输入这些数据,更新成功则清空这些临时数据

    【结果】

    乐观锁在并发操作问题上,保证了业务效率和数据的正确性,基本可以采用这种方案解决交易中并发问题。

    ●悲观锁:指在应用程序中显式地为数据资源加锁。悲观锁假定当前事务操

    纵数据资源时,肯定还会有其他事务同时访问该数据资源,为了避免当前

    事务的操作受到干扰,先锁定资源。尽管悲观锁能够防止丢失更新和不可

    重复读这类并发问题,但是它会影响并发性能,因此应该很谨慎地使用悲

    观锁。

    ●乐观锁:乐观锁假定当前事务操纵数据资源时,不会有其他事务同时访问

    该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作。应用

    程序采用版本控制手段来避免可能出现的并发问题。

  • 相关阅读:
    D. Babaei and Birthday Cake--- Codeforces Round #343 (Div. 2)
    Vijos P1389婚礼上的小杉
    AIM Tech Round (Div. 2) C. Graph and String
    HDU 5627Clarke and MST
    bzoj 3332 旧试题
    codeforces 842C Ilya And The Tree
    codesforces 671D Roads in Yusland
    Travelling
    codeforces 606C Sorting Railway Cars
    codeforces 651C Watchmen
  • 原文地址:https://www.cnblogs.com/kongsq/p/5841386.html
Copyright © 2020-2023  润新知