Я работаю над проектом, в котором я выполняю много запросов, и время - это соображение, поэтому я хочу попробовать и реализовать многопоточность JDBC. Я не уверен, какой правильный способ сделать это.Правильная реализация многопоточности JDBC с помощью JNDI
Вот мой первый проект внедрения:
Spring Datasource Bean:
private DataSource ds;
@Resource(name="jdbc")
public void setDataSource(DataSource ds) {
this.ds = ds;
}
Initialization метод:
public void checkUsersMulti(List<User> users) throws Exception {
if(users!= null || users.size() != 0) {
ExecutorService executorService = Executors.newFixedThreadPool(20);
Queue<User> queue = new ConcurrentLinkedQueue<>();
queue.addAll(users);
for (Useruser: users) {
executorService.submit(new ProcessUser(queue));
}
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Runnable Класс:
Метод DAOclass ProcessUser implements Runnable {
private final Queue<User> queue;
public ProcessUser(Queue<User> queue) {
this.queue = queue;
}
public void run() {
try {
Connection conn = ds.getConnection();
User user = null;
while((user = queue.poll()) != null) {
userDao.getUser(user , conn));
}
DbUtils.closeQuietly(conn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Пользователь:
public User retrieveUser(User user, Connection conn) {
PreparedStatement st = null;
ResultSet rs = null;
try {
String sql = "SELECT firstname, lastname FROM users WHERE id= ?;
st = conn.prepareStatement(sql);
st.setString(1, user.getId());
rs = st.executeQuery();
while(rs.next()) {
user.setFirstName(rs.getString("firstname"));
user.setLastName(rs.getString("lastname"));
}
} catch (Exception e) {
return null;
}
finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(st);
}
return user;
}
UPDATE: Tomcat JNDI соединения Параметры пула:
<Resource
name="jdbc"
auth="Container"
type="javax.sql.DataSource"
maxTotal ="25"
maxIdle="30"
maxWaitMillis ="10000"
driverClassName="***Vendor Driver***"
url="***Valid URL"
username="***Valid Username***"
password="***Valid Password***"
/>
Однако, я получаю эту ошибку иногда:
java.sql.SQLException: Cannot get a connection, pool error Timeout waiting for idle object
Но процесс по-прежнему завершен, как ожидалось, - это может быть в настройках JNDI. Моя большая проблема заключается в том, что это «правильный» способ реализовать это. Я предположил, что лучше всего удерживать объект соединения, поэтому им не нужно повторно инициализировать.
Каков размер 'users'? возникает проблема для любого размера 'users'? –
мой набор данных ~ 200 прямо сейчас, я постараюсь расширить и сжать его, чтобы посмотреть, что такое поведение. Я внедрил предложения @ rmalchow, но мне любопытно посмотреть, как он себя ведет. –