Java / SQL - executeUpdate()挂起并导致OutOfMemoryException

时间:2015-01-29 13:18:31

标签: java sql sql-server jdbc

我试图在我的表中执行相对简单的插入,但executeUpdate()方法会挂起,直到程序崩溃并出现OutOfMemoryException。我已成功在SQL Server Management Studio上执行了插入操作,并且我已将数据库设置为脱机并重新联机,因此我不认为该表可以被锁定。我也打印出我的代币,但没有一个是空的。

我的代码中是否有任何可疑内容?

if(commandCode.equals("RV")){
    StringTokenizer tokens = new StringTokenizer(fullLine,"^");

    String itemCallNumber=null;
    String itemCurrentLocation=null;
    String itemFormat=null;
    String itemHomeLocation=null;
    String itemLibrary=null;
    String itemType=null;
    String itemCat1=null;
    String itemCat2=null;
    String itemCat3=null;
    Integer itemPubYear=null;
    String stationLibrary=null;
    String userProfileName=null;
    String userCat1=null;
    String userCat2=null;       
    String userZipCode=null;
    String userLibrary=null;
    java.sql.Date userBirthdate=null;
    String clientType = null;


    while(tokens.hasMoreTokens()){
        String token = tokens.nextToken();
        System.out.println(token);
        if(token.startsWith("UZ")){
            String dateString = token.substring(2);
            SimpleDateFormat format = new SimpleDateFormat("M/d/yyyy");
            Date date = format.parse(dateString);

            userBirthdate=new java.sql.Date(date.getTime());;
        }
        if(token.startsWith("PG")){
            userCat1=token.substring(2);
        }
        if(token.startsWith("PH")){
            userCat2=token.substring(2);
        }

        if(token.startsWith("PE")){
            userProfileName=token.substring(2);
        }

        if(token.startsWith("UM")){
            userLibrary=token.substring(2);
        }
        if(token.startsWith("UB")){
            userZipCode=token.substring(2);
        }

        if(token.startsWith("IQ")){
            itemCallNumber=token.substring(2);
        }
        if(token.startsWith("IL")){
            itemCurrentLocation=token.substring(2);
        }
        if(token.startsWith("IK")){
            itemFormat=token.substring(2);
        }
        if(token.startsWith("IN")){
            itemHomeLocation=token.substring(2);
        }
        if(token.startsWith("NS")){
            itemLibrary=token.substring(2);
        }
        if(token.startsWith("IG")){
            itemType=token.substring(2);
        }
        if(token.startsWith("NX")){
            itemCat1=token.substring(2);
        }
        if(token.startsWith("NY")){
            itemCat2=token.substring(2);
        }
        if(token.startsWith("0A")){
            itemCat3=token.substring(2);
        }
        if(token.startsWith("IF")){
            itemPubYear=Integer.parseInt(token.substring(2));
        }
        if(token.startsWith("FE")){
            stationLibrary=token.substring(2);
        }

        if(token.startsWith("dC")){
            clientType=token.substring(2);
        }

    }


    String insert = "INSERT INTO dbo.RenewItem Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    PreparedStatement insertPS = connection.prepareStatement(insert);

    //These come from earlier in the code and are verified to be correct
    insertPS.setInt(1, id);
    insertPS.setTimestamp(2, ts);

    insertPS.setString(3, itemCallNumber);
    insertPS.setString(4, itemCurrentLocation);
    insertPS.setString(5, itemFormat);
    insertPS.setString(6, itemHomeLocation);
    insertPS.setString(7, itemLibrary);
    insertPS.setString(8, itemType);
    insertPS.setString(9, itemCat1);
    insertPS.setString(10, itemCat2);
    insertPS.setString(11, itemCat3);
    insertPS.setInt(12, itemPubYear);
    insertPS.setString(13, stationLibrary);
    insertPS.setString(14, userProfileName);
    insertPS.setString(15,userCat1);
    insertPS.setString(16, userCat2);
    insertPS.setString(17, userZipCode);
    insertPS.setString(18, userLibrary);
    insertPS.setDate(19, userBirthdate);
    insertPS.setString(20,clientType);

    insertPS.executeUpdate();

编辑:我已经能够大大隔离问题。它与大桌子上的周围SELECT *有关。在下面的代码中,已到达selectPS.close()但该方法永远不会返回。

        final Connection connection = DriverManager.getConnection(url);

        String select = "SELECT * FROM dbo.SirsiStat";
        PreparedStatement selectPS = connection.prepareStatement(select);
        ResultSet rs = selectPS.executeQuery();
        System.out.println("here");
        selectPS.close();

1 个答案:

答案 0 :(得分:1)

首先,必须必须处理JDBC资源,然后尝试学习PreparedStatement的正确用法或用途。

使用try-with-resource语法。此语法确保即使在异常之后也可以调用close()方法。

try(Connection cn=DriverManager.getConnection(url,user,pass)) {
  //statements

   String sql = "insert into tableName (columnOne, columnTwo) values (?,?)";
   try(PreparedStatement ps = cn.prepareStatement(sql)) {

      while(tokens.hasMoreTokens()) {
         //statements
        ps.setInt(1,valueForColumn1);
        ps.setString(2,valueForColumn2);
      }
   }
}

参考线程 - How to properly dispose of Connection, ResultSet, and Statement objects in a while loop?