I am FTP'ing a file from a remote server and inserting/updating it in my db. I am using MySql db. But I am seeing java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
exception and also the row is being inserted into my db at the same time. How can I resolve this issue?.
The error from the log is below:
SEVERE: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
at com.sun.gjc.spi.jdbc40.PreparedStatementWrapper40.executeQuery(PreparedStatementWrapper40.java:642)
at ft.util.KeyGenerator.generateKey(KeyGenerator.java:92)
at ft.util.KeyGenerator.generateKey(KeyGenerator.java:44)
at processes.FTPInbound.connectAndGetListOfFiles(FTPInbound.java:242)
at com.washpost.main.Main.main(Main.java:24)
at lockbox.beans.LOCKBOX_MessageBean.onMessage(LOCKBOX_MessageBean.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
The error points to rset = stmt.executeQuery ();
in the below code:
package com.washpost.ft.util;
import java.io.*;
import java.util.*;
import java.sql.*;
import java.util.logging.*;
public class KeyGenerator {
private static HashMap keyTbl = new HashMap();
private static Vector keyLock = new Vector();
private final static long MAX_KEY_COUNT = 999999999;
private final static int KEY_INC_COUNTER = 1;
public KeyGenerator() {
}
public static long generateKey(String sequenceName)
throws Exception {
long keyValue;
synchronized(keyLock) {
String key = sequenceName;
Key data = (Key) keyTbl.get(key);
if(data == null || (data.currentValue == data.maxValue)) {
// Need to put retry logic
keyValue = generateKey(sequenceName,KEY_INC_COUNTER);
if(keyValue == -1) {
throw new Exception ("SequenceName not in SEQUENCE_GENERATOR table :" + sequenceName );
}
data = new Key(keyValue,keyValue,keyValue + KEY_INC_COUNTER);
keyTbl.put(key,data);
}
keyValue = data.currentValue;
data.currentValue++;
return keyValue;
}
}
public static synchronized long generateKey(String sequenceName,int count)
throws Exception {
PreparedStatement stmt=null;
ResultSet rset=null;
Connection db_conn = null;
StringBuffer sql = new StringBuffer();
long key=-1;
long maxKeyCount;
String sqlSeqNum="";
try {
// db_conn = Utility.getConnection("PASDataSource");
db_conn = Util.getConnection("ftpds");
sql.append("SELECT SEQ_NUM ");
sql.append("FROM SEQUENCE_GENERATOR ");
//SJ 2009.02.11, commented and added line below
//sql.append("WHERE sequence_name = ? ");
sql.append("WHERE SEQUENCE_NAME = ? for update");
System.out.println(sql + "::" + sequenceName);
stmt = db_conn.prepareStatement(sql.toString());
stmt.clearParameters();
stmt.setString(1,sequenceName);
rset = stmt.executeQuery ();
// Iterate through the result set
while(rset.next()) {
key = rset.getInt(1);
// Update the key
}
rset.close();
stmt.close();
stmt = null;
rset = null;
if(key != -1) {
if((key + count) > MAX_KEY_COUNT) {
// reset key count
// key = 1;
sqlSeqNum = "";
}
else
sqlSeqNum = " seq_num + ";
sql = new StringBuffer();
sql.append("UPDATE SEQUENCE_GENERATOR SET SEQ_NUM = " + sqlSeqNum + count );
sql.append(" WHERE SEQUENCE_NAME = ? ");
sql.append(" AND SEQ_NUM = ? ");
stmt = db_conn.prepareStatement(sql.toString());
stmt.clearParameters();
stmt.setString(1,sequenceName);
stmt.setLong(2,key);
if(stmt.executeUpdate() != 1) {
System.out.println(
":Not able to generate a new UNIQUE key for sequence :" + sequenceName);
throw new Exception("Not able to generate a new UNIQUE key for sequence :" + sequenceName );
}
return key;
}
return -1;
}
catch (Exception e) {
System.out.println(e.getMessage());
throw e;
}
finally {
Util.release(db_conn, stmt, rset);
System.out.println("Closing Connection in KeyGenerator(generateKey).");
}}
}
The best thing would be control this using the auto increment of mysql. But if you have to control the keys in your application, you can use this classes...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.