2010-05-08 2 views
3

Действительно ли ResultSet Thread безопасен?IS ResultSet Thread safe

Мой вопрос возникает из-за того, что в моей программе я использовал различную инструкцию для каждого запроса, я объявил ResultSet как локальную переменную, но это дает мне ошибку Операции, которая не разрешена после закрытия ResultSet. Но мои утверждения работают, поскольку я использую инструкции в вставке и удалении запроса. Я прокомментировал часть ResultSet и не получил ошибку!

ответ

5

Настоящая проблема заключается в том, что вы делите объекты Statement между несколькими потоками. Каждый раз, когда вы выполняете «Заявление», ранее возвращаемый ResultSet автоматически закрывается. В этом случае объекты ResultSet «принадлежат» к другому потоку, который, возможно, еще не закончил его использование. Следовательно, исключение ...

Нельзя передавать объекты Connection, Statement/PreparedStatement или ResultSet между несколькими потоками. Каждый поток должен приобретать и выпускать собственные ресурсы.

+1

, но не сделал соединение для каждого ада, привело к большому количеству подключений и закрытию его evrytime привести к накладным расходам –

+0

Нет, если вы используете пул соединений.Кроме того, неэффективное решение лучше, чем «решение», которое ломается из-за ошибок параллелизма. –

+0

как вы оцениваете проксиометр для объединения пула? есть ли лучший инструмент, который можно использовать? –

3

Нет, ResultSet не должен подвергаться воздействию более чем одного потока.

У ResultSet никогда не должно быть больше масштаба, чем один метод: выполнить запрос, сопоставить ResultSet в объект или коллекцию и закрыть ResultSet в той же области, в которой он был создан.

Правильный способ закрытия ResultSet находится в блоке finally в собственном try/catch.

Посмотрел код в другом вопросе. Это требует серьезного, полного рефакторинга. Неудивительно, что у вас проблемы с этим. Вот несколько советов:

  1. Следуйте соглашениям по кодированию Sun Java. Это может показаться тривиальным, но все, что делает ваш код труднее читать, - плохая идея. Ваши классы «doComms» и «savetodatabase» нарушают соглашение «имена классов начинаются с заглавной буквы».
  2. Именование вопросов. «doComms» - это не моя идея хорошей абстракции.
  3. Магические числа/константы повсюду. Они сделают ваш код сложнее изменить позже.
  4. Java - объектно-ориентированный язык; вы пишете в другом стиле. Когда я вижу «insert studentinfo», это заставляет меня задаться вопросом, где находится класс Студента.
  5. Ваш JDBC-код не обрабатывает ресурсы должным образом.

Любопытно - вы пытаетесь научиться писать сервер? Есть ли причина, по которой вы не использовали бы механизм сервлета в качестве основы для этого приложения? Розетки - это очень низкое место, чтобы начать решать такую ​​проблему.

+0

Да, я пытаюсь написать сервер ... спасибо за ответ. –

+0

@ user335990 - но ** почему ** вы пытаетесь это сделать? –

2

Несколько раз, когда я писал JDBC с ручным кодированием, это было и уродливо, и подвержено ошибкам. Конечно, это может быть только я, но вы можете иметь гораздо лучшие результаты с использованием классов Spring JDBC data access. Вам не нужно использовать весь весенний контейнер, просто DataSource и класс JdbcTemplate весны.

Он применяет шаблон использования JDBC, который является поточно-безопасным и ресурсоемким.

+0

Согласитесь с этим. Вы изобретаете колесо, плохо. Я всего лишь для того, чтобы научить людей, как не стрелять себе в ногу, но может делать это только сразу. – bwawok