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數據庫。併發