Мне нужно решение для отмены долгосрочного оператора выбора.
Я использую Spring 3.0.2, iBatis 2.3.0 и Oracle 10g.
Мне удалось заставить его работать с простым JDBC, но поскольку выбор генерируется динамически через экран расширенного поиска, мне действительно нужно использовать iBatis.
Внутренний класс iBatis, отвечающий за создание / извлечение из кэша подготовленных операторов: com.ibatis.sqlmap.engine.execution.SqlExecutor . Внутренний метод, вызываемый для каждого вызова queryForList () / queryForObject () , является SqlExecutor's
public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException
Метод.
По соображениям производительности iBatis создает новый подготовленный оператор, только если он еще не существует для данного оператора выбора.
Подготовленные операторы хранятся / кэшируются в HashMap, где строка sql является ключом, а подготовленный оператор - значением.
После неудачных попыток найти другие решения, я думаю, что можно было бы поработать с AOP ( AspectJ ), чтобы попытаться навести точку на метод SqlExecutor.executeQuery () и как-то сохранить в сеансе HTTP Карта кэша iBatis и строка sql.
Когда пользователь попытается отменить длительный запрос, из другого потока будет сделана проверка, чтобы увидеть, существует ли уже подготовленный оператор в карте кэша iBatis для данной строки sql, ранее сохраненной в сеансе HTTP через АОП.
Если он существует, будет выполнен вызов Statement.cancel ().
Я не понимаю, почему подобное решение может мешать внутренним механизмам iBatis, поскольку, если подготовленный оператор будет отменен, будет выдано исключение SqlException ( ORA-01013 пользователь запросил отмену текущей операции ) и Ibatis будет правильно обрабатывать это, как и любой другой сгенерированный SqlException.
Использование Spring AOP не является опцией, поскольку позволяет только указывать методы, объявленные в объектах, управляемых контейнером Spring. Я не могу объявить SqlExecutor как bean-компонент Spring, потому что он создается и управляется внутри iBatis.
Еще не пробовали вышеуказанное решение с AspectJ, так как я не совсем знаком с фреймворком AspectJ.
Я не уверен, что это правильный подход для этого, но я не нашел другого решения, чтобы отменить подготовленный оператор, созданный iBatis, поскольку iBatis, кажется, не предлагает никакой поддержки для этого (также проверил myBatis).