<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 193,  comments - 520,  trackbacks - 0
    測試在sqlserver2000上進(jìn)行,對工作流操作的相關(guān)方法在單元測試?yán)镞M(jìn)行多線程并發(fā)。測試發(fā)現(xiàn)sqlserver出現(xiàn)死鎖的情況相當(dāng)多,一些典型的情況:

    1、對同一張表先insert再update是很快會引起死鎖的,不管操作的是否是同一記錄
    解決方法:對于同一記錄,需要調(diào)整hibernate的映射策略,使得一次insert完成操作。對于不同的記錄需要在代碼中手動flush,使得update先于insert。

    2、對兩張表進(jìn)行多次update操作時,兩張表交替update也會很快引起死鎖
    解決方法:在代碼中手動flush,保證對兩張表的update不會出現(xiàn)交替的情況。

    3、部分大范圍掃描的select和update混合也會導(dǎo)致死鎖
    解決方法:優(yōu)化sql,盡量減少sql語句,通過給po增加持久化字段的方式減少關(guān)聯(lián)查詢

    經(jīng)過優(yōu)化,大部分情況下數(shù)據(jù)庫死鎖的情況得以避免,另外奇怪的是通過事件探查器在死鎖時并未發(fā)現(xiàn)鎖升級的事件。但是在一些特殊情況下(例如多個并發(fā)匯聚的直接聯(lián)合),死鎖依舊發(fā)生。最后不得不對方法進(jìn)行synchronized關(guān)鍵字同步,這個通過synchronized flush完成。業(yè)務(wù)方法不必同步,最后批量操作數(shù)據(jù)庫時進(jìn)行同步。

    換oracle進(jìn)行測試,在未synchronized的情況下,未發(fā)生死鎖情況。由此可見sqlserver與oracle鎖實現(xiàn)機制存在很大的差別。對sqlserver鄙視之。另,同事說,sqlserver2005后性能和機制發(fā)生了很大的變化,未測試。

    補充一下我的一個最簡單情況下的測試用例:
    PO:
    public class TestPO {
        String id;
        String name;
        
    int num;
        
        .
    }

    映射文件 hibernate3:
    <hibernate-mapping default-access="field">
      
    <class table="WFMS_TESTPO" name="com.eway.workflow.test.po.TestPO">

        
    <id name="id" column="ID"><generator class="uuid" /></id>

        
    <property name="name" column="NAME" type="string"/>

        
    <property name="num" column="NUM" type="integer"/>

      
    </class>
    </hibernate-mapping>

    被測試方法(都配置有事務(wù)):
        public void testSave(int num) {
            TestPO po 
    = new TestPO();
            po.setName(
    "ronghao");
            po.setNum(num);
            theadTestDao.save(po);
            po.setName(
    "haorong");
        }

        
    public void testSaveByJdbc(int num) {
            String sql 
    = "insert into WFMS_TESTPO (ID,NAME,NUM) values (?,'RONGHAO',?)";
            Object[] params 
    = new Object[]{num,num};
            jdbcTemplate.update(sql, params);
            sql
    ="update WFMS_TESTPO set name='haorong' where id=?"  ;
            params 
    = new Object[]{num};
            jdbcTemplate.update(sql, params);
        }

    測試用例:
         public void testSave() throws Exception {
            TheadtestTemplate template 
    = new TheadtestTemplate();
            template.execute(
    new TheadtestCallback() {
                
    public void doInThead(int suquence) {
    //               theadTestManager.testSave(suquence);
                    theadTestManager.testSaveByJdbc(suquence);
                }
            }, 
    10);
        }

    測試結(jié)果:不論是hibernate還是jdbc,并發(fā)情況下都很快就會引起sqlserver2000的死鎖,換用兩種數(shù)據(jù)庫驅(qū)動jtds和jturbo死鎖的情況沒有變化。

    結(jié)論:sqlserver2000數(shù)據(jù)庫的lock配置策略,不支持,或者數(shù)據(jù)庫本身,就不支持對不同的行做同時操作(或者支持不完善),所謂的行鎖支持很不完善,死鎖情況非常容易發(fā)生。

    補充:我對數(shù)據(jù)庫的一些實現(xiàn)機制也并不是很了解,所以這里也只能列出現(xiàn)象而不能解釋死鎖的根本原因。另外感謝Alex的討論。


    http://www.tkk7.com/ronghao 榮浩原創(chuàng),轉(zhuǎn)載請注明出處:)
    posted on 2008-06-19 13:34 ronghao 閱讀(6270) 評論(22)  編輯  收藏 所屬分類: 工作日志

    FeedBack:
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-19 15:02 | Alex
    xd ,你配置了事務(wù)了嘛?  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-19 17:55 | flybean
    1、死鎖,還是鎖阻塞,這是個問題。
    2、悲觀并發(fā)、樂觀并發(fā)生來以久,各有優(yōu)缺點,搞清楚再來鄙視。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 09:14 | Alex
    1、對同一張表先insert再update是很快會引起死鎖的,不管操作的是否是同一記錄
    2、對兩張表進(jìn)行多次update操作時,兩張表交替update也會很快引起死鎖
    3、部分大范圍掃描的select和update混合也會導(dǎo)致死鎖

    如果連這些問題都解決不了,你覺得是數(shù)據(jù)庫問題,還是你的問題呢?

    別拿那么多名詞出來嚇人,這個招數(shù)我上小學(xué)的時候用來嚇唬老師的,現(xiàn)在已經(jīng)不用了。

    就撿最后一個說吧,樂觀鎖,如果你控制不了,還是就不要用了,您還就是老老實實的本分點,使用數(shù)據(jù)庫本地提供的鎖功能吧,犧牲點數(shù)據(jù)庫的性能,也總比你數(shù)據(jù)更新失敗要好,如果你非要使用hibernate的樂觀鎖,請控制好,內(nèi)存中的數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)一致性。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 09:28 | ronghao
    @Alex
    我想你并沒有弄明白問題的關(guān)鍵。樂觀鎖和悲觀鎖的作用是防止多個事務(wù)對同一數(shù)據(jù)操作產(chǎn)生沖突的兩種策略。而我的問題是多個線程(即多個事務(wù))并發(fā)操作不同的數(shù)據(jù)。不知道明不明白意思。
    ps:以前我也把這兩者的概念經(jīng)常混淆。
      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-20 09:29 | BeanSoft
    說不定是濫用 Hibernate 導(dǎo)致的后果  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 09:34 | ronghao
    @BeanSoft
    我倒真的認(rèn)為是數(shù)據(jù)庫的原因。
    一個簡單的例子:很簡單的po:
    String id;
    String name;
    兩個字段,執(zhí)行操作:
    TestPO po=new TestPO();
    po.setName("ronghao");
    dao.save(po);
    dao.flush();
    po.setName("haorong");
    配置事務(wù),單元測試兩個線程并發(fā),sqlserver2000下馬上死鎖。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 09:39 | ronghao
    @BeanSoft
    當(dāng)然,我并沒有用jdbc直接測試  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:12 | Alex
    @ronghao
    如果不是多線程,那么配置事務(wù)還有何用,如果所有操作都在同一個流水線上,那么配置事務(wù)不是浪費人民的感情嘛?

      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:18 | Alex
    使用hibernate樂觀鎖 如果導(dǎo)致你保存失敗,簡單點說,就是你的兩個線程或者多個線程所控制的內(nèi)存中的數(shù)據(jù)和數(shù)據(jù)庫中數(shù)據(jù)集已經(jīng)不一致了。

    如果使用悲觀鎖,導(dǎo)致你保存失敗,那么說明你事務(wù)配置的問題,或者至少說明你測試用例的事務(wù)配置有問題,要不你直接試試 jdbc 并且硬編碼事務(wù)看看。

    否則 sqlserver2000 真的不要玩了,兩個線程都是死鎖。。。

      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:20 | Alex
    同時操作同的記錄集合,一方面要看你數(shù)據(jù)庫使用什么lock策略,一方面還要看你代碼的控制。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:21 | Alex
    同時操作不同的記錄集合,一方面要看你數(shù)據(jù)庫使用什么lock策略,一方面還要看你代碼的控制.  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:21 | ronghao
    @Alex
    你的說法沒有錯。我想問題的原因在于死鎖的原因你我的理解有差異。
    你理解的是對數(shù)據(jù)庫表同一記錄并發(fā)操作引起數(shù)據(jù)庫死鎖,這個顯然是應(yīng)用程序應(yīng)該控制和避免的。
    而我的意思是并發(fā)操作某一動作,例如同時啟動100個工作流流程,這個盡管操作的是同一張表但是顯然是針對不同的記錄,此時,樂觀鎖、悲觀鎖都是沒有意義的。
    當(dāng)然,我對數(shù)據(jù)庫的一些實現(xiàn)機制也并不是很了解,所以這里也只能列出現(xiàn)象而不能解釋死鎖的根本原因。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:26 | ronghao
    @Alex
    補充說明一下,在我的測試中,不會出現(xiàn)兩個線程互相修改沖突的情況,甚至select也不會沖突,因為流程實例ID一開始就將所有的數(shù)據(jù)區(qū)分開來。我是并發(fā)啟動多個流程,然后并發(fā)提交這些流程。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:31 | Alex
    上面我也說了,如果你直接使用hibernate的樂觀鎖,那么最細(xì)粒度的數(shù)據(jù)其實是由你自己來控制的,只要保持內(nèi)存中的當(dāng)前的數(shù)據(jù)在需要保存時和數(shù)據(jù)庫中的保存相同的version 就可以了,然后不管 有多少個線程insert 或者 update ,只要每個線程都滿足這個要求,就能保存成功了,當(dāng)然,如果你的數(shù)據(jù)庫的lock配置策略,不支持,或者數(shù)據(jù)庫本身,就不支持對不同的行做同時操作(或者支持不完善),所謂的行鎖,那么肯定會像你所說的那樣發(fā)生死鎖。
      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:37 | Alex
    @ronghao
    如果每個線程只處理 某一個或一些獨立 流程id相關(guān)的數(shù)據(jù),而沒有交叉數(shù)據(jù),那么還會出現(xiàn)這種現(xiàn)象。

    1.使用jdbc做這種測試,排除是否是hibernate的使用或者h(yuǎn)ibernate本身對2000支持的問題問題。(jdbc驅(qū)動也很關(guān)鍵。)
    2.查閱sql2000 對行鎖的支持程度。
      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:45 | ronghao
    @Alex
    哈哈,正如你說的,我想問題在這里:
    當(dāng)然,如果你的數(shù)據(jù)庫的lock配置策略,不支持,或者數(shù)據(jù)庫本身,就不支持對不同的行做同時操作(或者支持不完善),所謂的行鎖,那么肯定會像你所說的那樣發(fā)生死鎖。
    這也是我想表達(dá)的。我想有時間應(yīng)該請個專業(yè)的DBA來,我也查過了SQLSERVER的鎖機制,但是具體到這里理解還是存在問題。
    另外你對樂觀鎖的理解也很到位。如果是多個事務(wù)同時提交一個流程,樂觀鎖就會起作用。
      回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決[未登錄]
    2008-06-20 10:46 | ronghao
    @Alex
    好的,謝謝你的意見。我會用jdbc做這個測試。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-20 16:30 | BeanSoft
    是呀 JDBC 先測試下比較好 排除法 如果 JDBC 也不行 那八九成是 SQL Server 問題 坊間的傳言都認(rèn)為 SQL Server 好多地方不如 Oracle  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-21 19:45 | 鬼狗
    pk的這么熱烈丫, 我想可能先要搞清楚的是行鎖,頁鎖和表鎖這些基本概念,搞清楚不同數(shù)據(jù)庫的鎖機制,然后再來談樂觀鎖還是悲觀鎖會比較容易理解。

    我估計樓主缺少在sybase,db2下的工作經(jīng)驗, 所以才會這么激動。不同數(shù)據(jù)庫的設(shè)計本身是有相當(dāng)大差異的,很難說好壞,我印象中,缺省情況下對鎖的處理比較不傷腦筋的就是oracle了,其他的不管是sybase還是db2都不是缺省就可以很輕松做到高并發(fā)的,但是處理的好,至少db2 可以做到不輸給oracle的高并發(fā)。 至于sql server ,tpc網(wǎng)站上去翻一下,可以發(fā)現(xiàn)sql server也是常客。

    但是早期oracle的開發(fā), 嗯, 我覺得在很多方面其實倒不如db2這樣的數(shù)據(jù)庫省事,比如大表和小表在sql中的位置,都會顯著影響sql性能。再比如sql是簡單好,還是復(fù)雜好,這2個數(shù)據(jù)庫也是相反的。

    這只能說明不同數(shù)據(jù)庫的機制是有很大差異的,用好一個數(shù)據(jù)庫需要點時間對他進(jìn)行比較深入的理解。現(xiàn)代程序員往往被各種框架屏蔽了底層,有時候也不是什么好事,以前項目中就有專門組織DBA對程序員進(jìn)行數(shù)據(jù)庫方面的培訓(xùn),目的也就是為了彌補這個問題。

    對于鎖的問題,在oracle9i&10g編程藝術(shù)那本書里,作者有很深入的介紹,也列舉了其他數(shù)據(jù)庫的處理情況。作者從其他數(shù)據(jù)庫轉(zhuǎn)向使用oracle的時候,對這個問題,貌似和樓主一樣震驚,呵呵。當(dāng)年我也有個項目,被db2的鎖機制,搞的的死去活來,呵呵。

    簡單的說,搖身要是高可靠性數(shù)據(jù)庫都只是知道寫sql這么簡單, 人家DBA還怎么活?  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-21 19:50 | 鬼狗
    另外不知道lz用的jdbc是什么版本? sqlserver 2000 的官方版本問題多多,印象中諸多特性都不支持。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-06-22 15:24 | ronghao
    @鬼狗
    呵呵,你的意見非常中肯。  回復(fù)  更多評論
      
    # re: 高并發(fā)測試下的一些問題及解決
    2008-07-03 22:55 | leekiang
    汗,我們公司做了很多項目了,可你們說的這些問題公司幾十號人沒有一個人清楚,那些項目能用嗎?請問。  回復(fù)  更多評論
      
    <2008年6月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    關(guān)注工作流和企業(yè)業(yè)務(wù)流程改進(jìn)。現(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網(wǎng)站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲免费一区二区| 亚洲视频人成在线播放| 91成人免费福利网站在线| 亚洲色大成网站www| 亚洲AV无一区二区三区久久| 国产一级淫片免费播放| 亚洲va中文字幕无码久久| 日本免费人成视频播放| 99久久免费国产精品特黄| 99久久99热精品免费观看国产| 久久九九免费高清视频| 天天综合亚洲色在线精品| 亚洲精品伊人久久久久| 亚洲色图校园春色| 亚洲AV无码精品色午夜在线观看| 亚洲一区二区视频在线观看| 国产精品无码一区二区三区免费| 一二三四免费观看在线电影| 2015日韩永久免费视频播放| 久久精品一区二区免费看| 国产视频精品免费视频| 一级毛片成人免费看a| 色屁屁www影院免费观看视频| 亚洲高清国产拍精品熟女| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 亚洲自偷精品视频自拍| 亚洲国产精品成人精品无码区在线 | 日韩午夜免费视频| 69成人免费视频无码专区| 人碰人碰人成人免费视频| 亚洲成a人片在线观看天堂无码| 国产亚洲精品影视在线| 亚洲综合一区二区三区四区五区 | 最近中文字幕mv手机免费高清| 18国产精品白浆在线观看免费| 久久精品国产免费观看三人同眠| 无码人妻久久一区二区三区免费 | 久久精品亚洲乱码伦伦中文| 亚洲爽爽一区二区三区| 国产偷窥女洗浴在线观看亚洲| 中文字幕亚洲日韩无线码|