Din kode er stort set korrekt. Undtagelsen, der opstår, når en dead lock opstår, er en SQLException
. Undtagelsens getSQLState()
metode giver returnerer en fejlkode, der giver yderligere oplysninger
om selve fejlen.
Du bør også vente et kort stykke tid mellem forsøgene for ikke at belaste din server for meget.
Som du klogt gættede, så indstil et maksimalt antal forsøg, ellers kan du ende i en uendelig løkke.
Den endelige kode kunne se sådan ud:
boolean oops;
int retries = 5;
Connection c = null;
Statement s = null;
ResultSet rs = null;
do
{
oops = false;
c = null;
s = null;
rs = null;
try
{
c = openConnection();
s = c.createStatement();
rs = s.executeQuery("SELECT stuff FROM mytable");
fiddleWith(rs);
}
catch (SQLException sqlex)
{
oops = true;
switch(sqlex.getErrorCode()())
{
case MysqlErrorNumbers.ER_LOCK_DEADLOCK:
// deadlock or lock-wait time-out occured
break;
...
}
Thread.sleep(1000); // short delay before retry
}
finally
{
if (rs != null) try {
rs.close();
} catch (SQLException e) {
// some error handler here
}
if (s != null) try {
s.close();
} catch (SQLException e) {
// some error handler here
}
if (c != null) try {
c.close();
} catch (SQLException e) {
// some error handler here
}
}
}
while (oops == true && retries-- > 0);
Det er klart, at ovenstående kode er suboptimal. Det kan være en god ide at skelne mellem fejl, der finder sted på forbindelsestidspunktet og fejl ved udførelsestidspunktet. Du kan også opdage, at der efter nogle fejl er lidt håb om, at endnu et forsøg vil virke (f.eks. forkerte legitimationsoplysninger eller SQL-syntaksfejl).
Du stillede mange spørgsmål, men jeg vil forsøge at besvare dem alle:
Ja, se ovenfor:SQLException
's er dem, med mere information leveret af getErrorCode()
eller getSQLState()
.
En SQLException
kunne kastes af stort set alle metoder af alle klasser fra java.sql
pakke.
Ja, se ovenfor.
Du må naturligvis ikke genskabe en PreparedStatement
mellem to forespørgsler. Du skal blot indstille nye værdier til dine parametre, før du kalder executeQuery()
en gang til. Selvfølgelig, hvis du har brug for at udføre en anden forespørgsel, så en ny PreparedStatement
er påkrævet.
Et (nyt) ResultSet
objekt returneres af Statement.executeQuery()
, som repræsenterer resultatet af forespørgslen. Sådan et objekt skaber du aldrig selv. Ideelt set vil du kalde ResultSet.close()
så hurtigt som muligt for at frigive hukommelsen.
Jeg råder dig kraftigt til at følge andet kapitel af denne vejledning ("Behandler SQL-sætninger").