2012-04-27 45 views
3

我正在加載測試應用程序並獲取死鎖錯誤。該場景是由10個不同的用戶同時插入和更新數據庫。我在網上擡頭,仍然找不到解決問題的方法。這裏附上我涉及的死鎖的示例代碼。當在同一時間執行UPDATE時獲取死鎖

任何人都可以給我一些建議,以解決僵局?先謝謝你。

SampleController: 

onSubmit(userAccount) 
{ 
    sampleBO.testDeadLock(userAccount.getUserAccountId()); 

} 

SampleBO:

public void testInsert(Long id) 
{ 
    sampleDAO.testInsert4(id);  
} 

public void testDeadLock(Long id) 
{ 
    testInsert(id); 
    sampleDAO.testUpdate4(id); 
} 

SampleDAO:

public void testInsert4(Long id) 
{ 
    StringBuffer sbSql = new StringBuffer(); 
    sbSql.append(" INSERT INTO Test "); 
    sbSql.append(" ("); 
    sbSql.append(" id, "); 
    sbSql.append(" note "); 
    sbSql.append(") "); 
    sbSql.append(" VALUES "); 
    sbSql.append(" ("); 
    sbSql.append(""+id+","); 
    sbSql.append(" 'test' "); 
    sbSql.append(")"); 

    //Execute SQL using Spring's JDBC Templates 
    this.getSimpleJdbcTemplate().update(sbSql.toString()); 
} 

public void testUpdate4(Long id) 
{  
    StringBuffer sbSql = new StringBuffer(); 
    sbSql.append(" UPDATE Test WITH(ROWLOCK) SET "); 
    sbSql.append(" note = 'test1111'"); 
    sbSql.append(" WHERE id="+id); 

    //Execute SQL using Spring's JDBC Templates 
    this.getSimpleJdbcTemplate().update(sbSql.toString()); 
} 
+1

SQL的哪些品牌和版本? – RBarryYoung 2012-04-27 22:30:20

+1

此外,請張貼表定義,包括任何鍵,索引,約束和/或觸發器,因爲它有90%可能是問題所在。 – RBarryYoung 2012-04-27 22:37:13

+0

我錯過了什麼?它看起來像是在同時調用兩個執行,所以testUpdate4調用在插入完成之前不應該觸發。 – Kir 2012-05-02 20:23:55

回答

0

如果死鎖正在發生,它不是來自你的代碼已經提供,除非:

  • 你有這個測試程序的多個實例運行在相同的位置 時間。
  • 上述代碼異步運行 - 但似乎並非如此。
  • 當您運行這些測試時,數據庫上還有其他活動。

我的錢是在最後一個。

您可以通過執行SQL跟蹤並確切確定正在運行什麼和何時發現這些死鎖發生的原因。


各自爲政,但你知道你可以聲明你的SQL查詢是這樣嗎? @允許文本進入多行,還可以轉義特殊字符,如反斜槓。

string sbSql = @" 
    INSERT INTO Test (id, note) 
    VALUES ({0}, 'test')"; 

sbSql = string.Format(sbSql, id); 

WITH(ROWLOCK)可能不需要。 99.9%的時間SQL服務器將執行相關的鎖定,並且您應該僅針對複雜或特殊情況明確強制某些鎖定。