2012-01-23 3 views
6

stiamo ottenendo eccezioni come questac3p0 - DEADLOCK apparente sulla MSSQL, ma non PostgreSQL o MySQL

com[email protected]5b7a7896 -- APPARENT DEADLOCK!!! Complete Status: 
Managed Threads: 3 
Active Threads: 3 
Active Tasks: 
    co[email protected]55bc5e2a (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 
    co[email protected]41ca435f (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) 
    co[email protected]460d33b7 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) 
Pending Tasks: 

quando test di carico la nostra applicazione su MSSQL 2008 R2 (jTDS o ufficiale MS JDBC non importa) . Non otteniamo mai questa eccezione quando eseguiamo gli stessi test con PostgreSQL o MySQL.

Non vogliamo solo aumentare il numero di thread di supporto per c3p0 (che risolve il problema, ma per quanto tempo?). Vogliamo sapere qual è il problema in quanto funziona con altri DBMS '.

Le applicazioni si comporta come:

  • Invia X richiede
  • Attendere per un po '-> DEADLOCK
  • Invia X richiede
  • Attendere per un po' -> DEADLOCK

Qualcuno sa o ha un'idea del perché abbiamo questo comportamento con MSSQL?

Grazie, Adrian

(Btw. BoneCP funziona senza alcun problema anche.)

+0

Che cos'è questa utilità e perché segnala "blocco apparente" anziché deadlock effettivo? SQL Server rileva i deadlock effettivi. È possibile tracciare il grafico del deadlock per poi diagnosticare il motivo per cui si verifica. –

+0

Ciao Martin, SQL Server stesso non ottiene deadlock. Sembra essere solo c3p0 (una lib di condivisione delle connessioni per Java) presuppone che ci sia stato un deadlock. – Adrian

+0

Adrian - puoi chiarire se usare BoneCP ha evitato il problema? – tgdavies

risposta

3

SQL Server dispone di una strategia di blocco molto più restrittiva rispetto a PostgreSQL o InnoDB.

Soprattutto bloccherà SELECTs su righe (tabelle?) Che vengono aggiornate da una connessione/transazione diversa (nell'installazione predefinita).

È necessario assicurarsi che non si stiano selezionando le stesse righe in una sessione che vengono aggiornate da un'altra.

Se non è possibile modificare la sequenza del codice, è possibile utilizzare "letture sporche" in SQL Server.

Se ricordo che correttamente, questo si ottiene con l'aggiunta di WITH NOLOCK alle istruzioni SELECT (ma non ne sono del tutto sicuro)

Modifica
Una possibilità diversa (se siete su SQL Server 2005 o più avanti) sarebbe quello di utilizzare il nuovo "isolamento dello snapshot" per evitare di selezionare i blocchi.

+0

SQL Server ha anche l'isolamento dello snapshot. –

+1

@ MartinSmith: lo so. Ecco perché ho detto "installazione predefinita". Ma avete un punto lì: passare all'isolamento dello snapshot potrebbe anche risolvere quel problema. –

+0

Non hai detto "installazione predefinita". Forse l'hai pensato! –