Java 在短时间内尝试 运行 一个 SQL 查询时挂起
Java hanging when trying to run an SQL Query for the second time in short succession
问题:
我有一些连接到数据库的代码,检查是否根据条件找到了记录,如果找到了记录,return 3 并生成一条消息供用户说已经存在包含这些详细信息的记录。如果记录不存在,则执行插入查询以创建记录。
问题是 select 查询在短时间内连续第二次执行时似乎挂起,结果是找到一条记录(return 3,生成消息到用户)- 因为它没有通过代码进行,没有错误报告并且程序上的 GUI 没有响应(无法单击任何其他对象并且无法响应关闭 window)。 Netbeans 仍然 运行 没问题,我可以通过它停止程序的 运行ning。
测试:
A) 如果我 运行 在我第一次成功执行后对同一个数据库进行另一个查询,但在另一个 table 上,代码执行正确,但返回尝试执行原始再次查询导致它挂起。
B) 执行代码并且 returning 没有结果不会导致它挂起。 (见下面的代码)
C) 扫描了 SE 上的其他类似问题,但似乎找不到解决我的问题的方法。
使用的资源:
ucanaccess-2.0.9.3,Netbeans IDE 8.1,JDK 1.8(由于与公司旧版本的兼容性问题编译为 1.6),公司网络上的 MS Access 数据库
代码:
public int insertAddPeriod(String strProjectNumber, String strYear, String strPeriod){
System.out.println("Checking to see if record already exists: " + strProjectNumber + ", Year: " + strYear + ", Period: " + strPeriod);
String strSQLString = null;
try{
strSQLString = "SELECT Program_No, Year, Period FROM tblCost WHERE Program_No = ? AND Year = ? AND Period = ?";
//SETTING PREPARED STATEMENT
PreparedStatement preStatement = con.prepareStatement(strSQLString, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
//SETTING FIRST CONDITION OF PREPARED STATEMENT IE ?
preStatement.setString(1, strProjectNumber);
preStatement.setString(2, strYear);
preStatement.setString(3, strPeriod);
ResultSet rs = preStatement.executeQuery();
if(rs.next()){
//CLOSES CONNECTIONS
rs.close();
preStatement.close();
System.out.println("Check Complete; Period Already Exists");
return 3;
}
else{
System.out.println("Check complete; No Previous Period");
System.out.println("Inserting record: " + strProjectNumber + ", Year: " + strYear + ", Period: " + strPeriod);
strSQLString = null;
try{
strSQLString = "INSERT INTO tblCost (Program_No, Year, Period) VALUES (?, ?, ?) ";
//SETTING PREPARED STATEMENT
PreparedStatement preStatement1 = con.prepareStatement(strSQLString, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
//SETTING FIRST CONDITION OF PREPARED STATEMENT IE ?
preStatement1.setString(1, strProjectNumber);
preStatement1.setString(2, strYear);
preStatement1.setString(3, strPeriod);
//EXECUTE QUERY
preStatement1.executeUpdate();
//CLOSES CONNECTIONS
preStatement1.close();
System.out.println("Insert Complete");
return 1;
}catch(Exception ex){
strEXMessage=ex.getMessage();
System.out.println(strEXMessage);
return 2;
}
}
}catch(Exception ex){
strEXMessage=ex.getMessage();
System.out.println(strEXMessage);
System.out.println("Check error; Unable to check for previous period");
return 2;
}
}
private void AddPeriod(){
//Create Connection
Database db = new Database();
int r = 0;
try {
r = db.CreateConnection();
} catch (SQLException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
//CONNECTION COMPLETE
if(r==1){
int q = 0;
q = db.insertAddPeriod((String)cbProjectNumber.getSelectedItem(),(String)cbCostYear.getSelectedItem(),(String)cbCostPeriod.getSelectedItem());
if(q==1){
System.out.println("Record");
JOptionPane.showMessageDialog(null,"Record added for the period: " + (String)cbCostPeriod.getSelectedItem(),"Complete",JOptionPane.WARNING_MESSAGE);
}
if(q==2){
System.out.println("Error");
JOptionPane.showMessageDialog(null,"There was an error processing the insert query","Error",JOptionPane.WARNING_MESSAGE);
}
if(q==3){
System.out.println("Missing");
JOptionPane.showMessageDialog(null,"Record already exists for the selected period","Error",JOptionPane.WARNING_MESSAGE);
}
}
//CONNECTION ERROR
if(r==2){
System.out.println("Error");
JOptionPane.showMessageDialog(null,"No connection made","Error",JOptionPane.WARNING_MESSAGE);
}
//CONNECTION RETURNS EMPTY
if(r==3){
System.out.println("No Records");
JOptionPane.showMessageDialog(null,"No records found in table","Missing Records",JOptionPane.WARNING_MESSAGE);
}
}
public int CreateConnection() throws SQLException, ClassNotFoundException{
try{
con = DriverManager.getConnection(strDBCon,strDBUser,strDBPass);
System.out.println("Connection Passed");
return 1;
}catch(SQLException ex){
strEXMessage=ex.getMessage();
System.out.println("Connection Failed: " + ex);
return 2;
}
}
public int CloseConnection(){
try{
con.close();
System.out.println("Connection Closed by User");
return 1;
}catch(SQLException ex){
strEXMessage=ex.getMessage();
return 2;
}
}
请忽略不整洁(除非这是原因),清理目前是 WIP。
通常这种情况下的无响应程序是由数据库的行锁引起的,由于尚未提交的插入、更新、删除。
正如我在您的代码中看到的那样,您没有提交准备好的语句。
您是否将自动提交设置为 true ?
如果没有,请在执行更新后用 con.commit() 尝试,第二次调用该方法应该可以正常工作。
问题:
我有一些连接到数据库的代码,检查是否根据条件找到了记录,如果找到了记录,return 3 并生成一条消息供用户说已经存在包含这些详细信息的记录。如果记录不存在,则执行插入查询以创建记录。
问题是 select 查询在短时间内连续第二次执行时似乎挂起,结果是找到一条记录(return 3,生成消息到用户)- 因为它没有通过代码进行,没有错误报告并且程序上的 GUI 没有响应(无法单击任何其他对象并且无法响应关闭 window)。 Netbeans 仍然 运行 没问题,我可以通过它停止程序的 运行ning。
测试:
A) 如果我 运行 在我第一次成功执行后对同一个数据库进行另一个查询,但在另一个 table 上,代码执行正确,但返回尝试执行原始再次查询导致它挂起。
B) 执行代码并且 returning 没有结果不会导致它挂起。 (见下面的代码)
C) 扫描了 SE 上的其他类似问题,但似乎找不到解决我的问题的方法。
使用的资源: ucanaccess-2.0.9.3,Netbeans IDE 8.1,JDK 1.8(由于与公司旧版本的兼容性问题编译为 1.6),公司网络上的 MS Access 数据库
代码:
public int insertAddPeriod(String strProjectNumber, String strYear, String strPeriod){
System.out.println("Checking to see if record already exists: " + strProjectNumber + ", Year: " + strYear + ", Period: " + strPeriod);
String strSQLString = null;
try{
strSQLString = "SELECT Program_No, Year, Period FROM tblCost WHERE Program_No = ? AND Year = ? AND Period = ?";
//SETTING PREPARED STATEMENT
PreparedStatement preStatement = con.prepareStatement(strSQLString, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
//SETTING FIRST CONDITION OF PREPARED STATEMENT IE ?
preStatement.setString(1, strProjectNumber);
preStatement.setString(2, strYear);
preStatement.setString(3, strPeriod);
ResultSet rs = preStatement.executeQuery();
if(rs.next()){
//CLOSES CONNECTIONS
rs.close();
preStatement.close();
System.out.println("Check Complete; Period Already Exists");
return 3;
}
else{
System.out.println("Check complete; No Previous Period");
System.out.println("Inserting record: " + strProjectNumber + ", Year: " + strYear + ", Period: " + strPeriod);
strSQLString = null;
try{
strSQLString = "INSERT INTO tblCost (Program_No, Year, Period) VALUES (?, ?, ?) ";
//SETTING PREPARED STATEMENT
PreparedStatement preStatement1 = con.prepareStatement(strSQLString, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
//SETTING FIRST CONDITION OF PREPARED STATEMENT IE ?
preStatement1.setString(1, strProjectNumber);
preStatement1.setString(2, strYear);
preStatement1.setString(3, strPeriod);
//EXECUTE QUERY
preStatement1.executeUpdate();
//CLOSES CONNECTIONS
preStatement1.close();
System.out.println("Insert Complete");
return 1;
}catch(Exception ex){
strEXMessage=ex.getMessage();
System.out.println(strEXMessage);
return 2;
}
}
}catch(Exception ex){
strEXMessage=ex.getMessage();
System.out.println(strEXMessage);
System.out.println("Check error; Unable to check for previous period");
return 2;
}
}
private void AddPeriod(){
//Create Connection
Database db = new Database();
int r = 0;
try {
r = db.CreateConnection();
} catch (SQLException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
//CONNECTION COMPLETE
if(r==1){
int q = 0;
q = db.insertAddPeriod((String)cbProjectNumber.getSelectedItem(),(String)cbCostYear.getSelectedItem(),(String)cbCostPeriod.getSelectedItem());
if(q==1){
System.out.println("Record");
JOptionPane.showMessageDialog(null,"Record added for the period: " + (String)cbCostPeriod.getSelectedItem(),"Complete",JOptionPane.WARNING_MESSAGE);
}
if(q==2){
System.out.println("Error");
JOptionPane.showMessageDialog(null,"There was an error processing the insert query","Error",JOptionPane.WARNING_MESSAGE);
}
if(q==3){
System.out.println("Missing");
JOptionPane.showMessageDialog(null,"Record already exists for the selected period","Error",JOptionPane.WARNING_MESSAGE);
}
}
//CONNECTION ERROR
if(r==2){
System.out.println("Error");
JOptionPane.showMessageDialog(null,"No connection made","Error",JOptionPane.WARNING_MESSAGE);
}
//CONNECTION RETURNS EMPTY
if(r==3){
System.out.println("No Records");
JOptionPane.showMessageDialog(null,"No records found in table","Missing Records",JOptionPane.WARNING_MESSAGE);
}
}
public int CreateConnection() throws SQLException, ClassNotFoundException{
try{
con = DriverManager.getConnection(strDBCon,strDBUser,strDBPass);
System.out.println("Connection Passed");
return 1;
}catch(SQLException ex){
strEXMessage=ex.getMessage();
System.out.println("Connection Failed: " + ex);
return 2;
}
}
public int CloseConnection(){
try{
con.close();
System.out.println("Connection Closed by User");
return 1;
}catch(SQLException ex){
strEXMessage=ex.getMessage();
return 2;
}
}
请忽略不整洁(除非这是原因),清理目前是 WIP。
通常这种情况下的无响应程序是由数据库的行锁引起的,由于尚未提交的插入、更新、删除。
正如我在您的代码中看到的那样,您没有提交准备好的语句。 您是否将自动提交设置为 true ? 如果没有,请在执行更新后用 con.commit() 尝试,第二次调用该方法应该可以正常工作。