中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

EF架構~關系表插(cha)入應該寫在(zai)事務里,但不應該是(shi)分布式(shi)事務

回到目錄

這(zhe)(zhe)(zhe)個(ge)(ge)標題很有意思,關系表(biao)(biao)插入(ru),就是說主表(biao)(biao)和外(wai)表(biao)(biao)鍵在插入(ru)時(shi),可(ke)能會(hui)有同(tong)步(bu)插的情況,如(ru)在建(jian)立主表(biao)(biao)時(shi),擴(kuo)展表(biao)(biao)需(xu)要同(tong)步(bu)完成數據(ju)(ju)(ju)的初(chu)始化工作(zuo),而對(dui)(dui)于多表(biao)(biao)插入(ru)時(shi),我們(men)為了保證(zheng)數據(ju)(ju)(ju)的一(yi)致性會(hui)針它寫在事(shi)(shi)務(wu)中(zhong),而對(dui)(dui)于.net中(zhong)的事(shi)(shi)件(jian),它在一(yi)些(xie)情況下,會(hui)不(bu)那么(me)單純,對(dui)(dui)于ef和linq to sql來(lai)說,你的事(shi)(shi)務(wu)如(ru)果出現多次提交動作(zuo)(submitchange | savechanges),那么(me),.net這(zhe)(zhe)(zhe)邊會(hui)把它提升(sheng)為分布式事(shi)(shi)務(wu)(MSDTC),即.net認(ren)為,對(dui)(dui)于一(yi)個(ge)(ge)數據(ju)(ju)(ju)表(biao)(biao)的操作(zuo),不(bu)會(hui)出現多個(ge)(ge)savechanges,OK,這(zhe)(zhe)(zhe)個(ge)(ge)可(ke)以解釋的通(tong),一(yi)個(ge)(ge)數據(ju)(ju)(ju)庫(ku),一(yi)個(ge)(ge)提交,這(zhe)(zhe)(zhe)是符(fu)合性能要求的,呵呵,但對(dui)(dui)于我們(men)的架構來(lai)說,有時(shi)一(yi)疏忽,就違背了.net的這(zhe)(zhe)(zhe)個(ge)(ge)原則,如(ru),我們(men)封裝的Insert方法,可(ke)能是這(zhe)(zhe)(zhe)樣(yang)的

   public virtual void Insert(TEntity item)
        {
       
            Db.Entry<TEntity>(item);
            Db.Set<TEntity>().Add(item);
            this.SaveChanges();
           
        }

這個代碼也沒有問題,在一個插入動作完成后,系統由SaveChanges方法完成一次提交(jiao),正是由于這樣的(de)代碼,所(suo)以我們的(de)麻(ma)煩(fan)就來了,如果(guo)是對兩個(ge)表的(de)操作嗎?

aRepository.Insert(a);
bRepository.Insert(b);

什么問題?數據一致性不能保(bao)證,因為沒有事務塊,呵呵,加上了再看看

  using (TransactionScope trans = new TransactionScope())
{
  aRepository.Insert(a);
  bRepository.Insert(b);
  trans.Commit();
}

OK,感覺是沒(mei)有問(wen)題(ti)了(le)(le),但細一(yi)想就會(hui)(hui)看出問(wen)題(ti)來了(le)(le),因(yin)為我們封裝的insert會(hui)(hui)有提(ti)交動作,所以,在這個事(shi)務塊中,.net會(hui)(hui)被認識是一(yi)個MSDTC(分布式(shi)的事(shi)務),原因(yin)是提(ti)交了(le)(le)多次,而如果你沒(mei)有打開msdtc服務的話,就會(hui)(hui)出現下面的黃屏了(le)(le)

注意:系統觸發分(fen)(fen)布(bu)式(shi)事務(wu)(wu)的(de)前提是你的(de)WEB服務(wu)(wu)器與(yu)數據庫服務(wu)(wu)器分(fen)(fen)別部(bu)署在兩(liang)個服務(wu)(wu)器上,一臺不(bu)會出現這個問題的(de)。

OK,這個MSDTC是(shi)怎么一回事,不是(shi)今天(tian)要說的(de)重要,如果想學(xue)習(xi)MSDTC,請看我的(de)這些(xie)文章:

 

第二十六回   將不確定變為確定~transactionscope何時提升為分布式事務?

第二十七回   將不確定變為確定~transactionscope何時提升為分布式事務~續

第二十八回   將不確定變為確定~transactionscope何時提升為分布式事務~再續(避免引起不必要的MSDTC)

第二十九回   將不確定變為確定~transactionscope何時提升為分布式事務~大結局

今天我們(men)要說的是在插(cha)入(ru)(ru)關系(xi)表時,怎樣(yang)使(shi)它(ta)不被提升為(wei)分布(bu)式事務,事實上(shang),怎么(me)做(zuo)我們(men)已(yi)經知道(dao)了,就(jiu)是方法中只出現一個savechages,呵(he)呵(he),而對(dui)于主(zhu)表與擴(kuo)展表來(lai)說,對(dui)于自增主(zhu)鍵(jian)(jian)的主(zhu)表,做(zuo)起來(lai)就(jiu)有(you)些麻煩了,呵(he)呵(he),我們(men)還需要借(jie)助SQL函(han)數(shu)來(lai)實現主(zhu)鍵(jian)(jian)的獲取工作,當主(zhu)鍵(jian)(jian)插(cha)入(ru)(ru)后,通過SQL函(han)數(shu)得到新值(zhi),然后再(zai)為(wei)擴(kuo)展表賦(fu)值(zhi),最后一些savechange()就(jiu)可以了,具體我們(men)看一下代碼:

  int maxID = Convert.ToInt32(new TsingDa_NewLearningBarEntities()//當前(qian)表最大ID
                  .Database.SqlQuery<decimal>("SELECT IDENT_CURRENT ('Classroom_Info')")
                  .First());
            using (TransactionScope trans = new TransactionScope())
            {
                try
                {
                    db.Entry<Classroom_Info>(entity);
                    db.Set<Classroom_Info>().Add(entity);

                    //綁(bang)定學生
                    entity.User_Classroom_R.ToList().ForEach(i =>
                    {
                        i.ClassroomInfoID = maxID + 1;
                        db.Entry<User_Classroom_R>(i);
                        db.Set<User_Classroom_R>().Add(i);
                    });
                    db.SaveChanges();//是(shi)否為(wei)msdtc就看它提交的(de)次數
                    trans.Complete();
                }
                catch (Exception)
                {
                    trans.Dispose();//出現異(yi)常,事務手動(dong)釋放(fang)
                    throw;
                }
            }

而(er)一(yi)(yi)次savechanges所產生的(de)SQL也是(shi)(shi)(shi)我(wo)們(men)(men)可以接受(shou)的(de),與服務器連(lian)接池中開啟一(yi)(yi)個新連(lian)接,然后把(ba)語句(ju)一(yi)(yi)條一(yi)(yi)條的(de)發過(guo)去,雖然不(bu)是(shi)(shi)(shi)一(yi)(yi)次性發送,但結(jie)果我(wo)們(men)(men)也是(shi)(shi)(shi)可以接受(shou)的(de),呵呵。

 

補充回復:

看了xiashengwang的 回復,我自己去試了一下,果然savechange將當前上下文中所有要提交的東西包在了一個事務塊里,出現異常后,自動完成callback,所以,對 于一個數據庫來說TransactionScope可以省去,而對于多個數據庫的操作,才需要使用TransactionScope,而對于何時將 TransactionScope提升為MSDTC的級別,到目前為止,我只能說,一個上下文的savechanges不會提升,多個 savechanges就會提升到msdtc,而矛盾是,一個savechanges的話,確實不需要外加TransactionScope塊了,呵呵, 這部分文章估計我還要繼續寫了,看看有沒有辦法在同一上下文多個savechanges操作時,不讓系統提升到MSTDC的級別,呵呵。

回到目錄

posted @ 2013-10-28 14:43  張占嶺  閱讀(4601)  評論(3)    收藏  舉報