我正在开发一个由Spring和Hibernate框架组成的应用程序。在一个特定模块中,应用程序从数据库中获取数据(选择查询)。沿着选择查询,应用程序还发出一个更新语句。经过进一步调试,我发现更新查询是从某个TransactionInterceptor触发的。我认为,这里不需要事务拦截器,因为所有都是选择查询。有人可以建议我一种方法来禁用/抑制这个拦截器在运行时?这个问题乍听起来可能太抽象了。然而,我对这个应用程序是新手,对它的体系结构了解不多。如果您需要任何配置细节,请告诉我。先谢谢你。
tez616oj1#
你能发布你的application-context.xml事务管理声明部分吗?这里的豆子:org.springframework.jdbc.datasource.DataSourceTransactionManager的定义。如果注解未启用,则应像这样激活它:
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" />
字符串
cqoc49vn2#
方法上的@Transactional(propagation = Propagation.NOT_SUPPORTED)将禁用此代理方法调用上的任何Spring事务。请注意,禁用事务也会失去其他好处,如隔离。但是,您触发更新查询的事实并不是因为事务。如果您只是简单地删除事务,则可能会遇到不同的错误(可能是hibernate尝试在事务之外更新时出现陈旧对象异常,或者某些模块发生故障)。Hibernate不会触发虚假的更新,您应该在事务期间查找对有问题的对象的更新。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
i7uq4tfw3#
下面是接口org.hibernate.Session方法clear()的JavaDoc:
org.hibernate.Session
clear()
ScrollableResults
所以当你使用clear时,你将清除整个会话。那好吧,你会问我:每个事务只有一个会话吗?我会回答你这取决于你的应用程序的HibernateTemplate配置,如果HibernateTemplate.alwaysUseNewSession==true,但默认值是false .解决方案是不要使用事务管理器拦截dao方法,因为默认情况下它将在非事务会话中执行。你看过Spring Framework AOP Proxy configuration了吗?截面10.5 Declarative transaction management
HibernateTemplate
HibernateTemplate.alwaysUseNewSession==true
false
10.5 Declarative transaction management
hc2pp10m4#
我通过在DAO类(扩展了HibernateDAOSupport)中编写以下代码来抑制更新查询第一个月我只是清除了会话,因为在获取数据时不需要更新,拦截器正在更新表。此外,我面临的最初问题是,应用程序在执行两次时遇到了来自此update语句的org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1(天知道为什么!).因此,我们发现从来不需要更新,并希望将其抑制。此修复会对应用程序产生任何影响吗?这样做对吗?会很感激你的投入。
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
neskvpey5#
因此,您的PlatformTransactionManager示例就是HibernateTransactionManager。TransactionInterceptor将事务处理委托给HibernateTransactionManager。这一切意味着:您对用@Transactional注解的数据访问方法所做的所有调用都将是路径抛出的Spring AOP代理(这是一种代理设计模式)。如果不使用基于注解的,并且已经声明了AOP代理(在ApplicationContext.xml中搜索aop:config标记)。因此,在AOP代理配置中,您将发现应用程序用于截获数据访问方法和处理事务的策略。如果您使用的是基于注解的查找,您应该知道什么是'transactionAttributeSource':注解交易属性来源或属性交易属性来源?
PlatformTransactionManager
HibernateTransactionManager
TransactionInterceptor
@Transactional
6tqwzwtp6#
如果在方法中只有select查询,则可以在@Transactional annotation(@Transactional(readOnly = true))中使用readOnly属性。Spring将使用它来优化底层的数据访问层操作(例如hibernate的“脏”检查)并提高性能。如果你的实体是never changes @org.hibernate.annotations.Immutable是另一种解决方案。但是,如果实体状态没有更改,update语句就不会出现,因此您应该检查代码中是否存在持久的实体更改。我同意禁用事务拦截器不是一个好的解决方案。
6条答案
按热度按时间tez616oj1#
你能发布你的application-context.xml事务管理声明部分吗?这里的豆子:
org.springframework.jdbc.datasource.DataSourceTransactionManager
的定义。如果注解未启用,则应像这样激活它:
字符串
cqoc49vn2#
方法上的
@Transactional(propagation = Propagation.NOT_SUPPORTED)
将禁用此代理方法调用上的任何Spring事务。请注意,禁用事务也会失去其他好处,如隔离。但是,您触发更新查询的事实并不是因为事务。如果您只是简单地删除事务,则可能会遇到不同的错误(可能是hibernate尝试在事务之外更新时出现陈旧对象异常,或者某些模块发生故障)。Hibernate不会触发虚假的更新,您应该在事务期间查找对有问题的对象的更新。
i7uq4tfw3#
下面是接口
org.hibernate.Session
方法clear()
的JavaDoc:ScrollableResults
的示例所以当你使用clear时,你将清除整个会话。那好吧,你会问我:每个事务只有一个会话吗?我会回答你这取决于你的应用程序的
HibernateTemplate
配置,如果HibernateTemplate.alwaysUseNewSession==true
,但默认值是false
.解决方案是不要使用事务管理器拦截dao方法,因为默认情况下它将在非事务会话中执行。你看过Spring Framework AOP Proxy configuration了吗?截面
10.5 Declarative transaction management
hc2pp10m4#
我通过在DAO类(扩展了HibernateDAOSupport)中编写以下代码来抑制更新查询
第一个月
我只是清除了会话,因为在获取数据时不需要更新,拦截器正在更新表。
此外,我面临的最初问题是,应用程序在执行两次时遇到了来自此update语句的
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
(天知道为什么!).因此,我们发现从来不需要更新,并希望将其抑制。
此修复会对应用程序产生任何影响吗?这样做对吗?会很感激你的投入。
neskvpey5#
因此,您的
PlatformTransactionManager
示例就是HibernateTransactionManager
。TransactionInterceptor
将事务处理委托给HibernateTransactionManager
。这一切意味着:您对用@Transactional
注解的数据访问方法所做的所有调用都将是路径抛出的Spring AOP代理(这是一种代理设计模式)。如果不使用基于注解的,并且已经声明了AOP代理(在ApplicationContext.xml中搜索aop:config标记)。因此,在AOP代理配置中,您将发现应用程序用于截获数据访问方法和处理事务的策略。如果您使用的是基于注解的查找,您应该知道什么是'transactionAttributeSource':注解交易属性来源或属性交易属性来源?6tqwzwtp6#
如果在方法中只有select查询,则可以在@Transactional annotation(@Transactional(readOnly = true))中使用readOnly属性。Spring将使用它来优化底层的数据访问层操作(例如hibernate的“脏”检查)并提高性能。如果你的实体是never changes @org.hibernate.annotations.Immutable是另一种解决方案。但是,如果实体状态没有更改,update语句就不会出现,因此您应该检查代码中是否存在持久的实体更改。我同意禁用事务拦截器不是一个好的解决方案。