Застревание при выполнении CallableStatement в приложении SpringBoot

#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 сделает все это за вас.