我已经开始研究一个项目,在这个项目中,我有两个表在不同的数据库中使用不同的模式。所以我将有两个不同的连接参数来连接数据库。在连接到每个数据库之后,我需要使用相应表中给出的sql插入这两个表。
我应该根据命令行参数插入所有两个表或其中任何一个使用JDBC。这意味着单个线程将插入Table1和Table2或其中任何一个。
命令行参数: - 这里10是线程数,100是任务数,table1和table2是表名。
10 100 table1 table2
以下是我的代码。在这段代码中会发生什么 - 假设我们只传递一个名为table1
的表,那么它将通过使用用于table1的SQL插入到该表中。
此外,我还需要在id
和table1
中插入相同的table2
,id
将AtomicInteger
作为Task
传递给构造函数{{1} }。这意味着如果id is 1
,则1 id
和table1
中的table2
都应该存在。
final AtomicInteger id = new AtomicInteger(1);
ExecutorService service = Executors. newFixedThreadPool(noOfThreads);
for (int i = 0; i < noOfTasks * noOfThreads; i++) {
for (String arg : tableNames) {
String url = (String) prop.get(arg + ".url");
String user = (String) prop.get(arg + ".user");
String password = (String) prop.get(arg + ".password");
String driver = (String) prop.get(arg + ".driver");
String suffix = (String) prop.get(arg + ".suffix");
String sql = (String) prop.get(arg + ".sql");
service.submit( new Task(id, url, user, password, driver, sql, suffix));
}
}
下面是实现Runnable接口的Task类
class Task implements Runnable {
private final AtomicInteger id ;
private final String url ;
private final String username ;
private final String password ;
private final String sql ;
private final String driver ;
private final String suffix ;
public Task(AtomicInteger id, String url, String user, String password, String driver, String sql, String suffix) {
this.id = id;
this.url = url;
this.username = user;
this.password = password;
this.driver = driver;
this.sql = sql;
this.suffix = suffix;
}
@Override
public void run() {
try {
dbConnection = getDBConnection(url , username , password , driver );
callableStatement = dbConnection .prepareCall(sql);
int userId = id .getAndIncrement();
callableStatement.setString(1, String.valueOf(userId));
//other callableStatement
callableStatement.executeUpdate();
}
}
因此,如果我选择10
,如果我运行上述程序,其中多个线程如线程数为1000
,任务数为id
和1
。
然后在两个表中,相同的ID不存在,这意味着id 1将只存在于table1
或table2
的一个表中。我能想到的唯一原因是id
是AtomicInteger
所以每次为每个线程获得一个新的id
。有什么办法可以在每个表中使用相同的id插入吗?然后确保id为PrimaryKey
,这样如果每个线程再次插入这些表中,它们将获得一个新的id。
答案 0 :(得分:0)
如果我理解正确,您应该将计数器定义为静态,以避免重复PrimaryKey
:
static AtomicInteger id;
然后将增量代码移动到主循环中(不要忘记删除int userId = id .getAndIncrement();
类中的Task
):
for (int i = 0; i < noOfTasks * noOfThreads; i++) {
// add following line
int userId = id.getAndIncrement();
for (String arg : tableNames) {
String url = (String) prop.get(arg + ".url");
String user = (String) prop.get(arg + ".user");
String password = (String) prop.get(arg + ".password");
String driver = (String) prop.get(arg + ".driver");
String suffix = (String) prop.get(arg + ".suffix");
String sql = (String) prop.get(arg + ".sql");
service.submit( new Task(id, url, user, password, driver, sql, suffix));
}
}
此外,由于id
计数器保留在内存中,您可能需要保留它,否则在重新启动应用程序后它将重置为0.