• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    sqlserver2000上在單元測試里進行多線程并發出現的死鎖情況

    發布: 2009-9-21 09:39 | 作者: webmaster | 來源: 本站原創 | 查看: 113次 | 進入軟件測試論壇討論

    領測軟件測試網

    sqlserver2000上在單元測試里進行多線程并發出現的死鎖情況   軟件測試

    測試在sqlserver2000上進行,對工作流操作的相關方法在單元測試里進行多線程并發。測試發現sqlserver出現死鎖的情況相當多,一些典型的情況:

    1、對同一張表先insert再update是很快會引起死鎖的,不管操作的是否是同一記錄

            解決方法:對于同一記錄,需要調整hibernate的映射策略,使得一次insert完成操作。對于不同的記錄需要在代碼中手動flush,使得update先于insert。

    2、對兩張表進行多次update操作時,兩張表交替update也會很快引起死鎖

            解決方法:在代碼中手動flush,保證對兩張表的update不會出現交替的情況。

    3、部分大范圍掃描的select和update混合也會導致死鎖

            解決方法:優化sql,盡量減少sql語句,通過給po增加持久化字段的方式減少關聯查詢

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

            換oracle進行測試,在未synchronized的情況下,未發生死鎖情況。由此可見sqlserver與oracle鎖實現機制存在很大的差別。另,同事說,sqlserver2005性能和機制發生了很大的變化,未測試。

            補充一下我的一個最簡單情況下的測試用例: PO:

    view plaincopy to clipboardprint?
    public class TestPO {  
     
        String id;  
     
        String name;  
     
        int num;  
     
         
     
        ....  
     

    public class TestPO {

        String id;

        String name;

        int num;

      

        ....

    }映射文件 hibernate3: view plaincopy to clipboardprint?
    <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> 

    <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>被測試方法(都配置有事務): view plaincopy to clipboardprint?
    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(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);

        }測試用例: view plaincopy to clipboardprint?
         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);  
     
        } 

         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);

        }

            測試結果:不論是hibernate還是jdbc,并發情況下都很快就會引起sqlserver2000的死鎖,換用兩種數據庫驅動jtds和jturbo死鎖的情況沒有變化。 結論:sqlserver2000數據庫的lock配置策略,不支持,或者數據庫本身,就不支持對不同的行做同時操作(或者支持不完善),所謂的行鎖支持很不完善,死鎖情況非常容易發生。 補充:我對數據庫的一些實現機制也并不是很了解,所以這里也只能列出現象而不能解釋死鎖的根本原因。

     

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: 單元 死鎖 線程


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>