在OQL上使用UPDLOCK锁定查询结果,安全的更新实体数据

栏目: 数据库 · 发布时间: 7年前

内容简介:SqlServer查询记录的时候提供多种锁定方式,其中UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改。看下面的查询:这个示例中,在读取记录后,等待10秒来模拟耗时的操作,之后再更新这条记录。

SqlServer查询记录的时候提供多种锁定方式,其中UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改。

看下面的查询:

begin tran
select * from address WITH (UPDLOCK) where [Name]='Z'
waitfor delay '00:00:10' 
update address set [Name]='X' where [Name]='Z' 
commit tran

这个示例中,在读取记录后,等待10秒来模拟耗时的操作,之后再更新这条记录。

上面这个例子可能比较抽象,让我们来举一个实际的例子。

假设有一个投资产品表,当我们查询到该产品记录后,要进行一系列的判断,最后对该记录进行更新。该记录的状态会影响到下一个人查询到此记录的处理。下面我们来看看用SOD框架的OQL怎么处理。

           decimal sumAmount = model.Amount + model.GvMoney;
            DateTime currentTime = DateTime.Now;
            AdoHelper db = AdoHelper.CreateHelper("defaultDB");
            
            db.BeginTransaction();
            try
            {
                //查询相关产品余额剩多少够不够买的
                var pro = EntityQuery<Pro_Products>.QueryObject(
                    OQL.From<Pro_Products>()
                        .With(OQL.SqlServerLock.UPDLOCK)
                        .Select()
                        .Where<Pro_Products>((cmp, p) => cmp.Property(p.proNumber) == model.ProNumber)
                        .END, db);
                if (pro == null)
                {
                    db.Rollback();
                    return new OrderingModel { Msg = "剩余可投金额不足" };
                }
                //2015 08 06 打开原有注释,限制投资金额  
                if (sumAmount < 10 || sumAmount % 10 != 0)
                {
                    db.Rollback();
                    return new OrderingModel { Msg = "投标金额不正确" };
                }

                //线下标下单时,不可使用现金券 
                if (SetObject.IsOffline(pro.ProType))
                {
                    sumAmount = model.Amount;
                }
                if (pro.Surplus < sumAmount)
                {
                    db.Rollback();
                    return new OrderingModel { Msg = "剩余可投金额不足" };
                }
                if (currentTime < pro.starttime)
                {
                    db.Rollback();
                    return new OrderingModel { Msg = "还未开始" };
                }
                var giveAward = 0;
                if (pro.Surplus == sumAmount)
                {
                    if (sumAmount >= 5000 && sumAmount < 10000)
                    {
                        giveAward = 1;
                    }
                    if (sumAmount >= 10000)
                    {
                        giveAward = 2;
                    }
                }
                //扣除产品可用金额
                pro.Surplus -= sumAmount;
                if (pro.Surplus == 0)//最后一笔 更新满标状态
                {
                    pro.Prostatus = "2";
                    //pro.Paymentime = currentTime.AddDays(1);
                    pro.Paymentime = currentTime;
                    //
                    pro.ProOrder = 0;
                }

                EntityQuery<Pro_Products>.Instance.Update(pro, db);
 
                //其它复杂的处理逻辑,更新其它表的操作,略...

                  db.Commit();

上面的操作,首先在AdoHelper对象上开启事务,然后查询投资产品实体的时候在With方法上加上 OQL.SqlServerLock.UPDLOCK 更新锁,接着进行复制的业务处理,然后更新此实体记录,之后还有复杂的其它业务操作,最后提交事务。

我们看到,OQL的这种更新锁操作,跟直接写 SQL 语句操作很类似,OQL执行的时候也是这样输出SQL语句的,这样确保数据记录在并发的时候,安全的更新。

注意:OQL更新锁目前只支持SqlServer数据库。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

需求

需求

[美] 亚德里安•斯莱沃斯基(Adrian J. Slywotzky)、[美]卡尔•韦伯 (Karl Weber) / 魏薇、龙志勇 / 浙江人民出版社 / 2013-6 / 64.9

《财富汇•需求:缔造伟大商业传奇的根本力量》内容简介:需求,是缔造伟大商业传奇的根本力量。《财富汇•需求:缔造伟大商业传奇的根本力量》呈现了人们无法拒绝、竞争对手无法复制的需求创造的六大关键,在人们无奈接受的现状和心中真正期待的理想的这道鸿沟之上,架设起了一道桥梁。 创造需求,需要解开一个谜团,这个谜团是人类学、心理学、科技、设计、经济学、基础设施以及其他众多因素综合而成的奇特组合。《财富汇......一起来看看 《需求》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试