我正在一个应用程序中工作,需要在足够长的时间内在DB2表中填充大量数据和各种数据。所以我在代码中进行了更改,以便在不同的线程中填充数据,比如
public class ThreadPopulator implements Runnable
{
volatile private boolean isTaskCompleted;
volatile private Connection db2Conn;
volatile private List<Data> list;
volatile private String srcLib;
public ThreadPopulator(Connection db2Conn, List<Data> list, String srcLib)
{
this.db2Conn = db2Conn;
this.list = list;
this.srcLib = srcLib;
}
public void run()
{
try
{
isTaskCompleted = false;
execute(srcLib, list);
}
catch (Throwable e)
{
}
}
synchronized private void execute(String srcLib, List<Data> list)
{
PreparedStatement stmt = null;
int len = list.size();
for (int i = 0; i < len; i++)
{
try
{
if (stmt == null)
stmt =
db2Conn.prepareStatement("INSERT INTO DATA VALUES(?, ?, ?, ?)",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
Data data = list.get(i);
stmt.setString(1, srcLib);
stmt.setString(2, "VV");
stmt.setDouble(3, data.getSeq());
stmt.setInt(4, data.getDate());
stmt.addBatch();
if ((i + 1) % 5000 == 0)
stmt.executeBatch(); // Execute every 5000 items.
}
catch (Exception e)
{
}
}
try
{
if (len > 0)
stmt.executeBatch(); //for remaining records
}
catch (Exception e)
{
}
finally
{
stmt.close();
if (list != null) list.clear();
isTaskCompleted = true;
}
}
public static ThreadPopulator insert(Connection db2Conn, ArrayList<Data> list, String srcLib)
{
ThreadPopulator populator = new ThreadPopulator(db2Conn, srcLib);
Thread thread = new Thread(populator);
thread.start();
return populator;
}
}
然后我收到错误: DB2 SQL错误:SQLCODE = -805,SQLSTATE = 51002,SQLERRMC = NULLID.SYSLH21E 。意味着已打开语句的数量超过了大约13K的限制,因此我进行了一些日志记录以查看正在创建的语句数量(通过在prepareStatement()上递增一个静态计数器并通过递减close()),并且发现没有递减是发生,因为没有调用close(),总语句数达到22K。
所以我最后做了一些更改来创建一个静态语句对象,并在所有线程中使用该实例作为
private static PreparedStatement stmt = null;
public static void createStatement(Connection db2Conn)
{
try
{
if (stmt == null)
{
stmt =
db2Conn.prepareStatement("INSERT INTO DATA VALUES(?, ?, ?, ?)",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
}
catch (Exception e)
{
}
}
现在一切正常。但作为Java开发人员,我对这种技术并不满意。即创建一个静态变量,然后在所有线程中使用该对象。
你能否告诉我什么是最好的设计 在线程中创建/使用语句,它也适用于我的情况 好。
提前致谢。
答案 0 :(得分:2)
这些情况下的常见做法是使用某种connection pool;数据库驱动程序需要实现此功能。您可以在IBM的DB2 documentation找到有关DB2实现的信息。