2011-03-03 30 views
3

我需要一个解决方案来取消长时间运行的select语句。 我使用Spring 3.0.2,iBatis 2.3.0和Oracle 10g。 我设法让它与普通的JDBC一起工作,但因为select是通过高级搜索屏幕动态生成的,所以我确实需要使用iBatis。如何取消iBatis准备的语句?

负责从预处理语句的缓存中创建/检索的iBatis内部类是com.ibatis.sqlmap.engine.execution.SqlExecutor。呼吁的queryForList()/ queryForObject()的每一个电话的内部方法是SqlExecutor的

public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException 方法。

由于性能原因,iBatis的创建只有一个,如果不存在针对给定的select语句新准备好的声明。 准备好的语句存储/缓存在一个HashMap中,其中sql字符串是键,准备语句是值。

没有成功尝试不同的其他解决方案后,我认为有可能与AOP(的AspectJ)合作,尝试切点的SqlExecutor.executeQuery()方法,并以某种方式存储在HTTP会话iBatis的高速缓存地图和SQL字符串。

当用户尝试取消长时间运行的查询时,将从另一个线程进行检查,以查看iBatis缓存映射中是否存在预先存储在HTTP会话中的给定sql字符串的预准备语句通过AOP。 如果确实存在,则会发出Statement.cancel()调用。 我不明白为什么这样的解决方案可能与iBatis的内部机制干扰,因为如果准备好的语句将被取消,一个SQLException将被抛出(请ORA-01013用户取消当前操作的)和iBatis将妥善处理与任何其他生成的SqlException一样。

使用Spring AOP不是一个选项,因为它只允许您切入由Spring容器管理的对象中声明的方法。我不能将SqlExecutor声明为Spring bean,因为它是由iBatis在内部创建和管理的。

还没试过用AspectJ上述解决方案,因为我不是很熟悉AspectJ的框架。

我不确定这是否是正确的方法,但我没有找到另一种解决方案来取消由iBatis创建的预备语句,因为iBatis似乎没有提供任何支持(也有检查myBatis)。

+0

我不知道iBatis或这应该如何正确完成。不过,从AspectJ的角度来看,这对我来说将是一个很好的挑战。所以,如果你想为我从GitHub中克隆一些[MCVE](http://stackoverflow.com/help/mcve),包括Maven构建和针对某些内存数据库的长时间运行声明,那么我会看到我能为你做什么。顺便说一句,使用编译时编织来创建一个方面增强的iBatis库以便在生产中稍后使用,或者您更喜欢LTW(加载时编织)吗? – kriegaex 2018-01-14 02:56:45

+0

@kriegaex这个问题已经接近7岁了,我怀疑OP会有任何使用它的情况下,如果有人回答。也许OP应该删除这个问题,因为它看起来不像是一个能够帮助其他人的问题。 – 2018-01-14 03:06:48

+0

对不起,我没有注意到。它刚刚出现在我的AspectJ RSS源中,因为无论出于何种原因,这个问题编辑了5个小时。很有趣,不是吗?感谢提示,Nándor。顺便说一句,似乎他没有在[MyBatis邮件列表](http://mybatis-user.963551.n3.nabble.com/Canceling-Statements-td2549512.html)上得到答案。 – kriegaex 2018-01-14 03:15:45

回答

0

您是否尝试过让哪个正在运行的声明,以及连接无效连接的参考?