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

jmo0nnb3  于 2023-08-02  发布在  Spring
关注(0)|答案(6)|浏览(105)

我正在开发一个由Spring和Hibernate框架组成的应用程序。在一个特定模块中,应用程序从数据库中获取数据(选择查询)。沿着选择查询,应用程序还发出一个更新语句。经过进一步调试,我发现更新查询是从某个TransactionInterceptor触发的。我认为,这里不需要事务拦截器,因为所有都是选择查询。有人可以建议我一种方法来禁用/抑制这个拦截器在运行时?
这个问题乍听起来可能太抽象了。然而,我对这个应用程序是新手,对它的体系结构了解不多。如果您需要任何配置细节,请告诉我。
先谢谢你。

tez616oj

tez616oj1#

你能发布你的application-context.xml事务管理声明部分吗?这里的豆子: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" />

字符串

cqoc49vn

cqoc49vn2#

方法上的@Transactional(propagation = Propagation.NOT_SUPPORTED)将禁用此代理方法调用上的任何Spring事务。请注意,禁用事务也会失去其他好处,如隔离。
但是,您触发更新查询的事实并不是因为事务。如果您只是简单地删除事务,则可能会遇到不同的错误(可能是hibernate尝试在事务之外更新时出现陈旧对象异常,或者某些模块发生故障)。Hibernate不会触发虚假的更新,您应该在事务期间查找对有问题的对象的更新。

i7uq4tfw

i7uq4tfw3#

下面是接口org.hibernate.Session方法clear()的JavaDoc:

  • 完全清除会话。逐出所有加载的示例并取消所有挂起的保存、更新和删除。不要关闭打开的迭代器或 * ScrollableResults的示例

所以当你使用clear时,你将清除整个会话。那好吧,你会问我:每个事务只有一个会话吗?我会回答你这取决于你的应用程序的HibernateTemplate配置,如果HibernateTemplate.alwaysUseNewSession==true,但默认值是false .解决方案是不要使用事务管理器拦截dao方法,因为默认情况下它将在非事务会话中执行。
你看过Spring Framework AOP Proxy configuration了吗?截面10.5 Declarative transaction management

hc2pp10m

hc2pp10m4#

我通过在DAO类(扩展了HibernateDAOSupport)中编写以下代码来抑制更新查询
第一个月
我只是清除了会话,因为在获取数据时不需要更新,拦截器正在更新表。
此外,我面临的最初问题是,应用程序在执行两次时遇到了来自此update语句的org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1(天知道为什么!).
因此,我们发现从来不需要更新,并希望将其抑制。
此修复会对应用程序产生任何影响吗?这样做对吗?会很感激你的投入。

neskvpey

neskvpey5#

因此,您的PlatformTransactionManager示例就是HibernateTransactionManagerTransactionInterceptor将事务处理委托给HibernateTransactionManager。这一切意味着:您对用@Transactional注解的数据访问方法所做的所有调用都将是路径抛出的Spring AOP代理(这是一种代理设计模式)。如果不使用基于注解的,并且已经声明了AOP代理(在ApplicationContext.xml中搜索aop:config标记)。因此,在AOP代理配置中,您将发现应用程序用于截获数据访问方法和处理事务的策略。如果您使用的是基于注解的查找,您应该知道什么是'transactionAttributeSource':注解交易属性来源或属性交易属性来源?

6tqwzwtp

6tqwzwtp6#

如果在方法中只有select查询,则可以在@Transactional annotation(@Transactional(readOnly = true))中使用readOnly属性。Spring将使用它来优化底层的数据访问层操作(例如hibernate的“脏”检查)并提高性能。如果你的实体是never changes @org.hibernate.annotations.Immutable是另一种解决方案。但是,如果实体状态没有更改,update语句就不会出现,因此您应该检查代码中是否存在持久的实体更改。我同意禁用事务拦截器不是一个好的解决方案。

相关问题