Váš kód je v podstatě správný. Výjimka vyvolaná při zablokování je SQLException
. Výjimka je getSQLState()
metoda poskytuje chybový kód, který poskytuje další informace
o skutečné chybě.
Mezi jednotlivými pokusy byste také měli chvíli počkat, abyste příliš nezatížili server.
Jak jste chytře uhodli, nastavte maximální počet pokusů, jinak se můžete dostat do nekonečné smyčky.
Konečný kód by mohl vypadat takto:
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);
Je zřejmé, že výše uvedený kód není optimální. Možná budete chtít rozlišit chyby, ke kterým dochází v době připojení, a chyby v době provádění. Můžete také zjistit, že po některých chybách je malá naděje, že další pokus bude fungovat (např. nesprávné přihlašovací údaje nebo chyba syntaxe SQL).
Ptali jste se na spoustu otázek, ale pokusím se na všechny odpovědět:
Ano, viz výše:SQLException
's jsou ty, přičemž další informace poskytuje getErrorCode()
nebo getSQLState()
.
SQLException
mohl být vyvolán prakticky všemi metodami všech tříd z java.sql
balíček.
Ano, viz výše.
Samozřejmě nesmíte znovu vytvářet PreparedStatement
mezi dvěma dotazy. Před voláním executeQuery()
stačí nastavit nové hodnoty parametrů znovu. Samozřejmě, pokud potřebujete provést další dotaz, pak nový PreparedStatement
je vyžadováno.
A (nový) ResultSet
objekt vrací Statement.executeQuery()
, který představuje výsledek dotazu. Sami takový objekt nikdy nevytvoříte. V ideálním případě zavoláte ResultSet.close()
co nejdříve, abyste uvolnili paměť.
Důrazně vám doporučuji sledovat druhou kapitolu tohoto návodu ("Zpracování příkazů SQL").