#java #oracle #spring-boot #callable-statement
#java #Oracle #весенняя загрузка #вызываемый оператор
Вопрос:
Когда я запускаю свой CallableStatement
to PL / SQL DB, он застревает. Я думаю, что это проблема основного потока, но я не знаю, как это исправить.
Мой OracleService
класс:
@Service
public class OracleService {
private static final Logger LOG = LoggerFactory.getLogger(OracleService.class);
private static final String PROCEDURE = "{ call <USER>.<PACKAGE>.<PROCEDURE_NAME>(?, ?) }";
@Autowired
private OracleConfig oracleConfig;
public void testProcedure() {
try (Connection connection = oracleConfig.connection()) {
connection.setAutoCommit(true);
CallableStatement callableStatement = connection.prepareCall(PROCEDURE);
int index = 1;
Date currDate = new Date();
callableStatement.setDate(index , new java.sql.Date(currDate.getTime()));
callableStatement.registerOutParameter(index , OracleTypes.CURSOR);
callableStatement.execute(); // Here it is getting stuck
// Processing data
} catch (SQLException e) {
e.printStackTrace();
}
}
}
И он вызывается простым CommandLineRunner
в Application
классе:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
CommandLineRunner lookup() {
return args -> {
OracleService service = new OracleService();
service.testProcedure();
};
}
}
Если кто-нибудь знает, пожалуйста, помогите мне)
Комментарии:
1. Вы уверены, что это не проблема в самой хранимой процедуре, а не проблема в коде, который ее вызывает?
2. Если процедура изменяет данные, то она может быть просто заблокирована незафиксированными изменениями в другом сеансе; например, если вы создали тестовые данные через клиента (разработчика SQL и т. Д.), Но не зафиксировали, Прежде чем пытаться вызвать процедуру из вашего приложения. Посмотрите, оставили ли вы что-нибудь в этом состоянии; есть запросы, которые вы можете запустить в БД, если вы не уверены и ничего не можете найти.
3. Вы используете Spring и Spring Boot, почему вы не используете a
JdbcTemplate
для выполнения кода. Вы открываете соединения за пределами Spring, что приводит к утечкам соединений. Кроме того, ваш размещенный здесь код просто не может работать, поскольку вы создаете новый экземплярOracleService
и вызываете для него методы.4. @M.Deinum как упоминалось выше, проблема была связана с глупыми незафиксированными изменениями. Да,
JdbcTemplate
это лучшая идея, спасибо! Я двигаюсь дальше. Кстати, код работает. Но, в любом случае, это плохой вариант использования)
Ответ №1:
Большое спасибо людям, которые отвечают на комментарии. Глупая проблема была связана с оператором SQL, ожидающим обновлений в моем клиенте. Будьте осторожны =)
PS: как @M.Как уже упоминалось, при использовании Spring лучшей практикой является извлечение Connection
s из JdbcTemplate
пула
Комментарии:
1. Нет, не лучше извлекать
Connection
s из пула внутриJdbcTemplate
, вы должны правильно использоватьJdbcTemplate
использованиеjdbcTemplate.getDataSource().getConnection()
— это та же плохая идея, что и в вашем исходном коде.2. @M.Deinum вы имеете в виду, что лучше было бы выполнить
SQL
с помощьюJdbcTemplate
? Не могли бы вы объяснить подробнее, пожалуйста3. Используйте
execute
update
методы , для выполнения запроса и позвольте Spring выполнять обработку ресурсов. Ваш код может быть урезан на 60% и без необходимости открывать / закрывать / фиксировать соединения / наборы результатов / операторы. Spring сделает все это за вас.