java – Spring Jdbc声明式事务已创建但未执行任何操作
作者:互联网
我试图在我的基于Spring的Web应用程序中配置声明式事务管理,它拒绝与我合作.
我有两个主要问题:
>在我们的dataSource(我们的应用程序需要)上将defaultAutoCommit设置为false会导致所有查询回滚,无论是否涉及事务.
>配置事务并创建代理类和事务方法,但似乎没有使用任何事务.
第一个问题是相当困惑,因为每个单独的查询都在数据库中回滚.这也包括SELECT语句.什么可能导致每个查询在数据库中回滚?
至于第二个问题,我的交易管理配置概述如下:
applicationContext.xml中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
default-autowire="byName">
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<!-- ensure that the above transactional advice runs for any execution
of an operation defined by a service in the service package -->
<aop:config>
<aop:pointcut id="serviceOperations" expression="execution(* foo.bar.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperations"/>
</aop:config>
<!-- similarly, don't forget the PlatformTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="fooService" class="foo.bar.service.FooService" />
<bean id="barService" class="foo.bar.service.BarService" />
<bean id="zapService" class="foo.bar.service.ZapService" />
</beans>
在我尝试解决此问题时访问过的所有教程和论坛中,我认为我的配置应该是正确的.但是,我并不完全了解aop和spring交易,所以我可能会遗漏一些至关重要的事情.
如上所述,我可以跟踪我的日志并查看为我的服务类创建的代理以及事务方法.但是,当我实际运行应用程序并跟踪日志时,我没有看到任何处理DataSourceTransactionManager的语句或正在创建,提交,回滚的事务等.
在我看来,实际上没有任何东西在运行,我非常困惑,因为我已经遵循了许多不同的教程并尝试了许多不同的方法,但它总是以这种情况结束.
我也相当确定我已正确设置我的log4j属性以接收来自DataSourceTransactionManager的消息,但我在下面提供它们以确保它不仅仅是我的记录错误.
我的log4j设置了以下记录器来尝试跟踪事务:
log4j.logger.org.springframework=INFO, file
log4j.logger.org.springframework.jdbc.datasource=DEBUG, file
log4j.logger.org.springframework.transaction=DEBUG, file
注意:我在DEBUG上运行了顶级记录器,这是我验证正在创建服务代理的地方.
有没有人对可能发生的事情有任何见解?我现在很困惑,因为我确实看到一些涉及创建交易的部分,但我没有看到任何交易被使用的任何迹象.
编辑:
JB Nizet要求提供的其他信息.
我的整个应用程序都是注释驱动的,所以我的服务bean用@Service注释,并通过基于名称的自动装配注入我的控制器.
以下是我的一个服务类的示例(名称已更改,但将反映我的applicationContext.xml).
@Service("zapService")
public class ZapService
{
/**
* Data access object which performs the database look up
*/
private ZapDAO zapDAO;
/**
* Add the given zap to the database
*
* @param zap a populated zap
*/
public void processNewZap(Zap zap)
{
zapDAO.processNewZap(zap);
}
}
如您所见,我的服务类只是控制器类和dao类之间的代理. DAO是我实际处理数据库连接的地方.
我相信我在某个地方读到了处理事务的服务,而不是dao类,这是处理事务时的首选方法.如果我错了,请纠正我.
ZapDAO类概述如下.
@Repository("zapDAO")
public class ZapDAO
{
/**
* Log4j logger for this class
*/
Logger logger = Logger.getLogger(ZapDAO.class);
/**
* Spring jdbc object to handle interacting with the database
*/
private JdbcTemplate jdbcTemplate;
public void processNewZap(Zap zap) {
... query constructing logic ...
this.jdbcTemplate.update(INSERT_ZAP_QUERY_SQL);
}
public void setDataSource(DataSource dataSource)
{
Assert.notNull(dataSource, "You must supply a valid data source");
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
}
我使用jdbcTemplate来处理我的连接和查询.
解决方法:
因此,经过几个小时的搜索,调试和撕掉我的头发,我终于偶然发现了this小宝石提供了所有的答案.
我从来没有怀疑过这样的问题但是按照上面链接中概述的步骤完美地工作了.
在我的dispatch-servlet.xml中,我最初声明了我的组件扫描,如下所示:
<context:component-scan base-package="foo.bar"/>
这是我所有应用程序bean的父包.因此,如上面的链接所述,Spring使用dispatcher-servlet.xml中不知道事务的服务bean从applicationContext.xml覆盖我的事务服务bean.
我所做的就是打破上面的组件扫描,只扫描包含非事务bean的文件夹.
<context:component-scan base-package="foo.bar.controller"/>
<context:component-scan base-package="foo.bar.model"/>
<context:component-scan base-package="foo.bar.service.display"/>
<context:component-scan base-package="foo.bar.service.security"/>
<!-- foo.bar.service gets scanned in applicationContext.xml and includes
transactions so we must make sure to not include it here. The transactional beans
will be overridden in that case -->
在此之后,我的交易完全符合预期,我终于在我的日志文件中看到了交易的足迹和DataSourceTransactionManager.这也解决了我在数据库中自动回滚的第一个初始问题.我想它一定与缺乏交易密切相关.
标签:spring-jdbc,spring-transactions,java,spring 来源: https://codeday.me/bug/20191007/1864768.html