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
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数据库。并发