Skip to content

MyBatis-Spring 事务

🏷️ MyBatis

参考官方文档 第四章 事务 实现了使用事务来更新数据。

  1. applicationContext.xml 中添加

    xml
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
  2. 对方法使用 @Transactional 注解

    java
    @RequestMapping(value = "update/{account}", method = RequestMethod.POST)
    @Transactional
    public int updUser(@PathVariable("account") String account) {
        return userMapper.updUserByAccount(account);
    }

容器管理事务

尝试实现 第四章 事务 的 容器管理事务 部分时遇到了些问题,最终没能成功运行起来。
=。=|||

  • 元素 "tx:jta-transaction-manager" 的前缀 "tx" 未绑定

    applicationContext.xml 的根元素 beans 中添加 xmlns:tx 属性,并且在 xsi:schemaLocation 属性中添加 tx 前缀的 schema

    修改后的 beans 属性如下:

    xml
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
        <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
            <tx:jta-transaction-manager/>
        </bean>
    </beans>
  • Configuration problem: Cannot locate BeanDefinitionDecorator for element [jta-transaction-manager]

    不知道如何解决~~

编程式事务管理

通过代码手动管理事务。

java
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * Created by liujiajia on 2019/1/23.
 */
@RestController
@RequestMapping("api/user")
public class UserController {
    @Resource
    private UserMapper userMapper;

    @Resource
    private DataSourceTransactionManager transactionManager;

    @RequestMapping(value = "update/{account}", method = RequestMethod.GET)
    public int updUser(@PathVariable("account") String account) {
        int updResult = 0;

        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            updResult = userMapper.updUserByAccount(account);
        } catch (Exception ex) {
            transactionManager.rollback(status);
            throw ex;
        }
        transactionManager.commit(status);

        return updResult;
    }
}

setPropagationBehavior 方法设置了事务的传播行为类型,共 7 种,具体说明如下:

事务传播行为类型说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

参考

  1. Spring7 种事务传播行为类型--PROPAGATION_REQUIRED 及其他 6 种事务传播行为种类
  2. spring 配置出现前缀 "tx" 未绑定、前缀 "mvc" 未绑定等情况
  3. 关于用 spring 的 JtaTransactionManager,配置分布式事务
  4. Spring jta-transaction-manager