【问题标题】:How to rollback transaction in Spring JDBC?如何在 Spring JDBC 中回滚事务?
【发布时间】:2017-09-30 08:30:26
【问题描述】:

我想在我的方法中进行多次插入,如果出现任何问题,我想回滚所有插入。 这是我的 jdbc bean 定义

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <context:property-placeholder location="classpath:jdbc.properties"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

这是我的方法

@Transactional
public void save(Map<String, String> properties, Long moduleId,
                 String language, String propertyFileName, String filePath) {

    KeyHolder keyHolder = new GeneratedKeyHolder();

    final String propertyFileQuery = "INSERT INTO property_file " +
            "(moduleId, languageId, propertyFileName,hash,path) " +
            "VALUES (?,?,?,?,?)";

    jdbcTemplate.update(connection -> {
        PreparedStatement ps =
                connection.prepareStatement(propertyFileQuery, new String[]{"id"});
        ps.setLong(1, moduleId);
        ps.setString(2, language);
        ps.setString(3, propertyFileName);
        ps.setString(4, "hash goes here");
        ps.setString(5, filePath);

        return ps;
    }, keyHolder);

    int x = 0 / 0;

    final String propertiesQuery = "INSERT INTO property_value " +
            "(propertyFileId, propKey, propValue) " +
            "VALUES (?,?,?)";

    properties.forEach((key, value) -> jdbcTemplate.update(
            propertiesQuery, keyHolder.getKey(), key, value
    ));

}

我希望它在遇到运行时异常0/0后回滚第一次插入

但是数据进入数据库,并没有回滚。

我做错了什么?

【问题讨论】:

    标签: java mysql spring jdbc transactions


    【解决方案1】:

    找出原因。事务管理没问题,我无法在事务中完成工作的原因是因为我的 MySQL 引擎。它被设置为MyISAM。 正如 MySQL 网站所引用的那样

    MyISAM 不支持事务并且可能永远不会支持。

    刚刚将表格从 MyISAM 更改为 InnoDb,然后就可以正常工作了。

    【讨论】:

      【解决方案2】:

      您可以将@Transactional 设置为您的类,而不是将其与单个方法绑定,因为当您将其绑定到一个类时,所有操作都将参与单个全局事务,如果任何事务失败,您的操作将回滚

      【讨论】:

        【解决方案3】:
        private PlatformTransactionManager transactionManager;
        
        public void setDataSource(DataSource dataSource) {
        
            this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
        
        public void setTransactionManager(PlatformTransactionManager transactionmanager) {
            this.transactionManager = transactionmanager;
        }
        

        在你必须使用的方法里面

            TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        

        jdbcTemplate.update之后你必须提交事务

                transactionManager.commit(status);
        

        您也可以使用@Transactional(propagation=Propagation.REQUIRED) `

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多