Java - 在异常后请求的时间内无法获得锁
Java - a lock could not be obtained within the time requested after exception
事情是这样的:
我有一个数据库作为记分板;
我有一个用新分数更新数据库的按钮;
我有一个 "developer exception" 每当分数低且无法替换记分板 (DB) 中的任何分数时抛出 SQLException;
问题:
- 我得到一个低分并且出现异常,然后我得到一个高分但是我没有更新数据库而是得到了错误。
这里是错误:
- "a lock could not be obtained within the time requested"
按钮中的代码如下:
try
{
Connection conec=DriverManager.getConnection(hostname,username,password); //<-- Conecçao com a base de dados
Statement stm=conec.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); //<-- Conecção com as tabelas
//------------Aquisição dos dados------------------//
SQL="SELECT * FROM DEMOLION.MINER";
res=stm.executeQuery(SQL);
//-------------------------------------------------//
res.first();
nome=JOptionPane.showInputDialog("Introduza o mone que deseja registar:","Jogador1");
Desktop.getDesktop().open(new File("Jogos RPG Maker/Miner mapa/Game.exe"));
pontuacao=JOptionPane.showInputDialog("Introduza a pontuação obtida:","0");
pontos=Integer.parseInt(pontuacao);
do
{
pontos_insuf();
dbpontos=res.getInt("PONTUACOES");
System.out.println("pt="+pontos+"db="+dbpontos);
if(pontos>dbpontos)
{
res.updateInt("PONTUACOES",pontos);
res.updateString("NOME",nome);
res.updateRow();
}
if(pontos<dbpontos || pontos==dbpontos)
{
res.next();
}
}
while(pontos<dbpontos);
stm.close();
res.close();
}
catch (IOException ex)
{
Logger.getLogger(Jogos_Pacman.NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
catch(SQLException e)
{
MsgBox.show(e.getMessage(),"AVISO", JOptionPane.INFORMATION_MESSAGE);
}
这里是开发者例外:
private void pontos_insuf() throws SQLException{
if(!res.next())
{
throw new SQLException("Obteve uma pontuação insuficiente para superar pontuações anteriores!");
} }
您正在使用 CONCUR_UPDATABLE 创建语句,我猜您的数据库需要锁,但是当抛出错误时您并没有释放锁,即您没有明确关闭陈述。
最好的情况是你受 GC 的支配来收集 Statement 并释放锁,最坏的情况永远不会发生。
您需要做的是移动这些语句:
stm.close();
res.close();
进入一个finally
块,这样它们无论如何都会发生
事情是这样的:
我有一个数据库作为记分板;
我有一个用新分数更新数据库的按钮;
我有一个 "developer exception" 每当分数低且无法替换记分板 (DB) 中的任何分数时抛出 SQLException;
问题:
- 我得到一个低分并且出现异常,然后我得到一个高分但是我没有更新数据库而是得到了错误。
这里是错误:
- "a lock could not be obtained within the time requested"
按钮中的代码如下:
try
{
Connection conec=DriverManager.getConnection(hostname,username,password); //<-- Conecçao com a base de dados
Statement stm=conec.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); //<-- Conecção com as tabelas
//------------Aquisição dos dados------------------//
SQL="SELECT * FROM DEMOLION.MINER";
res=stm.executeQuery(SQL);
//-------------------------------------------------//
res.first();
nome=JOptionPane.showInputDialog("Introduza o mone que deseja registar:","Jogador1");
Desktop.getDesktop().open(new File("Jogos RPG Maker/Miner mapa/Game.exe"));
pontuacao=JOptionPane.showInputDialog("Introduza a pontuação obtida:","0");
pontos=Integer.parseInt(pontuacao);
do
{
pontos_insuf();
dbpontos=res.getInt("PONTUACOES");
System.out.println("pt="+pontos+"db="+dbpontos);
if(pontos>dbpontos)
{
res.updateInt("PONTUACOES",pontos);
res.updateString("NOME",nome);
res.updateRow();
}
if(pontos<dbpontos || pontos==dbpontos)
{
res.next();
}
}
while(pontos<dbpontos);
stm.close();
res.close();
}
catch (IOException ex)
{
Logger.getLogger(Jogos_Pacman.NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
catch(SQLException e)
{
MsgBox.show(e.getMessage(),"AVISO", JOptionPane.INFORMATION_MESSAGE);
}
这里是开发者例外:
private void pontos_insuf() throws SQLException{
if(!res.next())
{
throw new SQLException("Obteve uma pontuação insuficiente para superar pontuações anteriores!");
} }
您正在使用 CONCUR_UPDATABLE 创建语句,我猜您的数据库需要锁,但是当抛出错误时您并没有释放锁,即您没有明确关闭陈述。
最好的情况是你受 GC 的支配来收集 Statement 并释放锁,最坏的情况永远不会发生。
您需要做的是移动这些语句:
stm.close();
res.close();
进入一个finally
块,这样它们无论如何都会发生