当前位置: 首页 > 面试题库 >

创建了Spring Jdbc声明式事务,但是什么也没做

闾丘淇
2023-03-14
问题内容

我试图在基于Spring的Web应用程序中配置声明式事务管理,但它拒绝与我合作。

我有两个主要问题:

  1. 在我们的数据源(我们的应用程序需要)上将defaultAutoCommit设置为false会导致 所有 查询回滚,无论是否涉及事务。
  2. 配置了事务,并创建了代理类以及事务方法,但是似乎没有事务在使用。

第一个问题是相当困惑,因为每个查询都正在数据库中回滚。这也包括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处理我的连接和查询。


问题答案:

所以在以后搜索,调试和撕扯我的头发小时小时,我终于偶然发现这其中所提供的所有答案的小宝石。

我绝对不会怀疑像这样的问题,但是按照上面链接中概述的步骤操作是可以的。

在我的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。这也解决了我的第一个数据库自动回滚问题。我想这一定与交易不足有关。



 类似资料:
  • 问题内容: 我很惊讶 评估为。 这段代码中发生了什么?真正和语句在做什么? 问题答案: 是一个特殊运算符,它等效于。 如果a和b绑定到同一对象,则运算符返回True,否则返回False。当创建两个空列表时,您将获得两个不同的对象,因此返回False(因此返回True)。

  • 声明式事务, 可以脱离Trans类实现单个方法或多个的事务模板. 例如设置Service类所有insert开头的方法,均应用READ_COMMITTED事务 声明式事务,是通过aop拦截器做的, 而aop依赖ioc, 在@IocBy注解中启用即可. @IocBy(type=ComboIocProvider.class, args={"*json","org/nutz/mvc/testap

  • 本文向大家介绍SpringBoot 注解事务声明式事务的方式,包括了SpringBoot 注解事务声明式事务的方式的使用技巧和注意事项,需要的朋友参考一下  springboot 对新人来说可能上手比springmvc要快,但是对于各位从springmvc转战到springboot的话,有些地方还需要适应下,尤其是xml配置。我个人是比较喜欢注解➕xml是因为看着方便,查找方便,清晰明了。但是xm

  • 10.5. 声明式事务管理 大多数Spring用户选择声明式事务管理。这是对应用代码影响最小的选择,因此也最符合非侵入式轻量级容器的理念。 Spring的声明式事务管理是通过Spring AOP实现的,因为事务方面的代码与Spring绑定并以一种样板式风格使用,不过尽管如此,你一般并不需要理解AOP概念就可以有效地使用Spirng的声明式事务管理。 从考虑EJB CMT和Spring声明式事务管理

  • 本文向大家介绍SpringMVC+MyBatis声明式事务管理,包括了SpringMVC+MyBatis声明式事务管理的使用技巧和注意事项,需要的朋友参考一下 采用的基本搭建环境:SpringMVC、MyBatis、MySQL、tomcat         Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的

  • 10.8. 选择编程式事务管理还是声明式事务管理 当你只有很少的事务操作时,编程式事务管理通常比较合适。例如,如果你有一个web应用,其中只有特定的更新操作有事务要求,你可能不愿使用Spring或其他技术设置事务代理。这种情况下,使用 TransactionTemplate 可能 是个好办法。 另一方面,如果你的应用中存在大量事务操作,那么声明式事务管理通常是值得的。它将事务管理与业务逻辑分离,而