I have a rather annoying issue. In the piece of code below, I am trying to insert a new row to the "RevisionDispersion" table in my database. However, whenever I call stmt.executeUpdate() the program freezes and there ends up being no transaction to the database. No matter how long I wait; the database just won't be updated. Below is the code of interest:
private static final String INSERT_DISPERSION = "insert into RevisionDispersion("
+ Assignments.ID + ", "
+ Persons.EMAIL + ", "
+ Handins.ID + ")"
+ " values(?, ?, ?)";
public static void disperse(DataSource source, Assignment assignment) throws Exception
{
List<String> handins = assignment.getHandins();
//used to decide who checks which assignment
int maxRNG = Math.max(1, handins.size() / assignment.getPeerCount());
int rng = new Random().nextInt(maxRNG);
PreparedStatement stmt = null;
Connection con = null;
try{
//Get the connection, set it to TRANSACTION_SERIALIZABLE and set autocommit to false
con = source.getConnection();
configureConnection(con);
//Prepare the statement to insert the new dispersion
stmt = con.prepareStatement(INSERT_DISPERSION);
stmt.setString(1, assignment.getID());
//Iterate over all hand-ins and decide from which peer a peer receives feedback
for(int i = 0; i < handins.size(); i++)
{
HandIn handin = new HandIn(source.getConnection(), handins.get(i));
String student = handin.getEmail();
stmt.setString(2, student);
for(int j = 1; j <= assignment.getPeerCount(); j++)
{
HandIn otherHandin = new HandIn(source.getConnection(), handins.get(j * rng));
stmt.setString(3, otherHandin.getId());
stmt.executeUpdate();
}
}
con.commit();
}catch(Exception e){
throw e;
}finally{
closeQuietly(con, stmt);
}
}
//This method is originally in the DBAO class, but I put it here for you folks.
protected static void configureConnection(Connection connection) throws SQLException
{
connection.setAutoCommit(false);
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
}
This problem occurs in no other places in the application. Whenever I run the SQL statement in SQL Server Management Studio, with identical parameters, it does not get stuck and it inserts the new rows just fine. After deleting the rows and trying the same in the application, it gets stuck.
Can anyone point me in the right direction of what is going wrong? I've been trying for 3 hours straight now...
Stuff I already tried
-use stmt.addBatch() rather than executeUpdate() (did not make a difference. It would get stuck at executeBatch())
-Check if all connections are being closed properly; they are.
-Check if other statements/resultsets are still open that use RevisionDispersion table (there are none still open. Even if there were, should not make a difference I think?)
-Completely delete the database and set it back up
I solved the issue...
In a different piece of code I had the following:
private static final String GET_NOT_DISPERSED = "select * from Assignments where "
+ Assignments.CLOSE_DATE + "<=? and "
+ Assignments.PEER_START_DATE + ">=? and "
+ Assignments.ID + " not in(select " + Assignments.ID + " from RevisionDispersion)";
private void makeMailDispersion() throws Exception
{
DateTime currentDate = DateTime.getCurrentDateTime();
PreparedStatement assignmentsStmt = null;
ResultSet assignments = null;
Connection con = null;
try{
con = source.getConnection();
configureConnection(con);
assignmentsStmt = con.prepareStatement(GET_NOT_DISPERSED);
assignmentsStmt.setString(1, currentDate.toString());
assignmentsStmt.setString(2, currentDate.toString());
assignments = assignmentsStmt.executeQuery();
ArrayList<Assignment> requiresDispersion = new ArrayList<>();
assignments.close();
assignmentsStmt.close();
while(assignments.next())
{
Assignment assignment = new Assignment(source.getConnection(), assignments.getString(Assignments.ID));
AssignmentDisperser.disperse(source, assignment);
}
}catch(Exception e){
throw e;
}finally{
closeQuietly(con, assignmentsStmt, assignments);
}
}
In this piece of code, I closed the variables 'assignments' and 'assignmentsStmt'. I thought this would be sufficient to unlock the table after having used the GET_NOT_DISPERSED query. Apparently it was not: the table was still locked.
What I had to do in order to fix it: aside from calling assignments.close() and assignmentsStmt.close() I also had to call con.close(). That completely unlocked the table and allowed the code to run properly.