在运行时禁用/忽略事务拦截器

时间:2014-05-13 15:57:51

标签: java spring hibernate

我正在开发一个由Spring和Hibernate框架组成的应用程序。在一个特定模块中,应用程序从数据库中获取数据(选择查询)。除了select查询,应用程序还会发出更新语句。进一步调试后,我发现更新查询是从某个TransactionInterceptor触发的。 我认为,这里不需要事务拦截器,因为所有都是选择查询。任何人都可以建议我在运行时禁用/抑制此拦截器的方法吗?

这个问题起初可能听起来过于抽象。但是,我是这个应用程序的新手,对它的架构知之甚少。如果您需要任何配置详情,请告知我们。

提前致谢。

5 个答案:

答案 0 :(得分:1)

您可以发布application-context.xml事务管理声明部分吗? bean:org.springframework.jdbc.datasource.DataSourceTransactionManager的定义。

如果没有启用注释,您应该像这样激活它:

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource" ref="yourDataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />

答案 1 :(得分:1)

@Transactional(propagation = Propagation.NOT_SUPPORTED) 在您的方法上将禁用此代理方法调用上的任何Spring事务。请注意,通过禁用事务,您还会失去其他好处,例如隔离。

但是,您触发更新查询的事实不是因为事务。如果您只是删除事务,则可能会遇到不同的错误(当hibernate尝试在事务外部更新时,可能是过时的对象异常,或某些模块的故障)。 Hibernate不会触发虚假更新,您应该在事务期间查找相关对象的更新。

答案 2 :(得分:1)

这里有接口​​org.hibernate.Session方法clear()

的JavaDoc

彻底清除会话。退出所有已加载的实例并取消所有挂起的保存,更新和删除。不要关闭打开的迭代器或 ScrollableResults

的实例

因此,当您使用clear时,您将清除整个Session。没关系,你会问我:每次交易我只有一个会话吗?我会回答你,如果HibernateTemplate但默认值为HibernateTemplate.alwaysUseNewSession==true,则取决于您的应用false配置。解决方案是不使用事务管理器拦截您的dao方法,因为它将在非事务会话中默认执行。

您是否看过Spring Framework AOP Proxy configuration。第10.5 Declarative transaction management部分

答案 3 :(得分:0)

我设法通过在我的DAO类(扩展HibernateDAOSupport)中编写以下行来禁止更新查询

super.getSessionFactory().getCurrentSession().clear();

我刚刚清除了会话,因为在获取数据和拦截器更新表时没有需要更新。

另外,我遇​​到的原始问题是,应用程序在执行两次时遇到来自此更新语句的org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1(天知道原因!)。

因此,我们发现从未需要更新,并希望对其进行抑制。

此修复程序可以对应用程序产生任何影响吗?这是正确的方法吗?将欣赏投入。

答案 4 :(得分:0)

因此,您的PlatformTransactionManager实例为HibernateTransactionManagerTransactionInterceptor会将事务处理委派给HibernateTransactionManager。所有这些意味着:您对使用@Transactional注释的数据访问方法所做的所有调用都将是路径抛出弹簧AOP代理(这是代理设计模式)。 如果您不使用基于注释的并且您已声明了AOP代理(在ApplicationContext.xml中搜索aop:config标记)。 因此,在AOP代理配置中,您将找到应用程序用于拦截数据访问方法和处理事务的策略。 要查找您是否使用基于注释,您应该知道什么是&#39; transactionAttributeSource&#39; :AnnotationTransactionAttributeSource或AttributesTransactionAttributeSource?