數據庫更新鎖WITH UPDLOCK

今天由於併發的問題,又討論了一遍。以前覺得同時兩個線程開啓,線程A加了更新鎖,線程B沒有加,線程A更新後,線程B也會繼續下去代碼。可是今天測試了一下,原來線程A更新後(解鎖),線程B將不會繼續,會出現數據庫語句出現修改之類的提示。sql

寫法 SELECT * FROM TABLE WITH UPDLOCK WHERE ID=1數據庫

A代碼段示例:併發

 using (TransactionScope trans = new TransactionScope())
                        {
                            using (var dbContext = new Qxun.Activity.DAL.ActivityDbContext())
                            {
string sqlStr = string.Format("SELECT * FROM TABLE WITH(UPDLOCK) WHERE ID={0} ", crossDomainPayRecord.ID);
                                VIPWeRegister046Play model = dbContext.Database.SqlQuery<VIPWeRegister046Play>(sqlStr).FirstOrDefault();
                            
                                if (Status == 0)//說明出現問題
                                {
                                    model.Status = Status;
                                    dbContext.Update<TABLE>(model);
                                    trans.Complete();
                                    return Content(res.ToXml());
                                }
                    trans.Complete();
                }
}                

B代碼段示例 :測試

using (ActivityDbContext dbContext=new ActivityDbContext())
            {
                List<TABLE> model= dbContext.TABLE.ToList();
                foreach (var item in model)
                {
                    item.Status= 2;
            dbContext.Insert<Table>(new Table());
                    dbContext.Update<TABLE>(item);
                }
 List<Share> share = dbContext.Shares.ToList();
                if (share.Count == 0)
                {
                    dbContext.Insert<Share>(new Share());
                }
                share = dbContext.Shares.ToList();
                foreach (var item in share)
                {
                    item.MerchantWeixinUserID = 1;
                    dbContext.Update<Share>(item);
                }
            }

 

 

1.線程A進入更新鎖代碼段,線程B將會中止在dbContext.Update處,不會再繼續下去(解鎖操做兩種:1.更新操做(非事務處理);2.事務處理結束(處於事務))線程

接下來有三種狀況:orm

1.1線程A不進行更新操做(沒有update操做,即便沒有改變值),線程A結束事務後(解鎖),線程B將繼續運行blog

1.2線程A進行了更新操做,即此時Status狀態值更改成0,線程B將會跳轉入異常,異常詳細上會有數據庫信息更改之類的提示事務

1.3線程A一直停留在斷點,不進行解鎖操做,時間一旦達到限制,則線程B將會提示請求超時之類的(因爲數據庫請求是有設定時限的)string

2.線程A未進入更新鎖代碼段,則線程B按照正常運行it

3.線程A進入更新鎖代碼段時,線程B也能夠使用select獲取,即List<TABLE> model= dbContext.TABLE.ToList();這句會被執行的,直到update操做中止

4.一旦A線程進入更新鎖代碼,且進行了update操做,線程B中的插入更新dbContext.Insert<Table>(new Table()); dbContext.Update<TABLE>(item);這兩句都不能執行,會出現報錯。而share表相關的insert和update也不能運行,這是由於share的代碼處理在TABLE下面,此時dbContext已經是異常狀態。若是將share放置到TABLE代碼上方,則會正常運行或者是將share從新開啓一個dbContext2進行操做。不過其中應該還有一些原因...

5.一旦A線程進入更新鎖代碼,且未進行update操做,線程B中的插入dbContext.Insert<Table>(new Table());代碼是會被執行的,且share相關的代碼都會被執行。

 

 

異常提示:存儲區更新、插入或刪除語句影響到了意外的行數(0)。實體在加載後可能被修改或刪除。刷新 ObjectStateManager 項。

相關文章
相關標籤/搜索