当前位置: 首页 > 知识库问答 >
问题:

发生错误时Spring事务管理无法工作

夏侯旻
2023-03-14

我想测试当一个数据库更新失败时,使用Spring JDBC的Spring事务管理是否正常工作。下面是我更新两个数据库表的代码:person和contact_info

public void createWithContactInfo(String username, String name, Date dob,
            String contactName, String contactPhone, String contactEmail) {

        try {
            String sqlStmt = "INSERT INTO person (username, name, dob) VALUES (?, ?, ?)";
            jdbcTemplateObject.update(sqlStmt, "paul", "Paul", dob);

            sqlStmt = "INSERT INTO contact_info(username, customer_name, contact_name, contact_phone, contact_email) VALUES (?, ?, ?, ?, ?)";
            jdbcTemplateObject.update(sqlStmt, username, name, contactName,
                    contactPhone, contactEmail);

        } catch (DataAccessException e) {
            e.printStackTrace();
        }
    }

我使用Spring声明性事务管理来配置bean:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="createWithContactInfo"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="createOperation"
        expression="execution(* com.example.db.CustomerJDBCTemplate.createWithContactInfo(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation" />
</aop:config>

<!-- Initialization for data source -->
<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/Customer" />
    <property name="username" value="myusername"/>
    <property name="password" value="12345"/>
    <property name="initialSize" value="10"/>
</bean>

<!-- Definition for customerJDBCTemplate bean -->
<bean id="customerJDBCTemplate" class="com.example.db.CustomerJDBCTemplate">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
public class JdbcTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        CustomerDAO dao = (CustomerDAO) ctx.getBean("customerJDBCTemplate");
        Date dob = new Date(90, 9, 10);
        dao.createWithContactInfo("m9087", "Sam", dob, "David", "123456", "a123@example.com");
    }
}
SELECT * FROM person WHERE username='paul'; 

我的理解是,事务应该回滚,如果任何DB操作失败,则不会进行提交。但是在这种情况下,即使第二次DB更新由于重复键异常而失败,第一次DB插入仍然成功。难道不是事务管理的错误行为吗?我在事务管理中的设置是否正确?

共有1个答案

麻烨
2023-03-14

它不会回滚,因为您正在捕获异常。当抛出未检查的异常时,将回滚事务。而你正在用你的catch块吞下它:

catch (DataAccessException e) {
    e.printStackTrace();
}
 类似资料:
  • 问题出在@Transactional中,在我的配置中spring应用程序没有使用它。我怎么能修好它? ...REST控制器没有任何事务性方法,它只使用specifiedServices加载实体。依赖集合(如果未加载到服务中)应为空。 应用程序启动程序类: 我还尝试将@Transactional添加到存储库接口中,但对我来说并不起作用 所以我从存储库中删除了@Transactional,创建了其他服

  • 我使用Grails2.3.3构建了一个成功的应用程序。 下面是PicturesNWSHR的域定义: -迈克

  • 问题内容: 我刚刚开始使用spring和hibernate进行项目。我的DAO图层类扩展了HibernateDaoSupport。我们没有使用注释。之前,我们使用了struts,因此我们使用了Session类提供的getTransaction,commit,rollback ..方法。我的要求非常简单,对于所有DAO类,如果有异常,则回滚,否则提交。请提出介绍spring交易管理的最简单方法。 问

  • Spring对RDBMS事务管理的支持在Spring WebFlux中也起作用吗? 例如,假设配置正确,用注释注释的方法是否会使用Spring事务管理器并在发生错误时回滚事务? 如果事务管理确实起作用,那么方法是否确实和异常,或者或返回类型是否发出错误信号? 我知道JDBC本质上是阻塞的,因此任何JDBC操作都必须从阻塞桥接到反应桥接,反之亦然。 我的组织有WebFlux和Cassandra的经验

  • 我想了解Spring Batch是如何进行事务管理的。这不是一个技术问题,而是一个概念性的问题:Spring Batch使用什么方法?这种方法的后果是什么? 让我试着澄清一下这个问题。例如,在TaskletStep中,我看到步骤执行通常如下所示: 准备步骤元数据的几个JobRepository事务 每一块要处理的业务事务 更多JobRepository事务,用区块处理的结果更新步骤元数据 这似乎是

  • 我使用的是Spring Boot 1.4.2中的spring-boot-starter-data-jpa。 一切都很好(@Entity classes discovery、datasource自动配置、transaction自动配置、EntityManager自动配置)。