首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis-Spring 事務管理完整整合指南

     編輯:Java 相關知識

核心依賴

<!-- MyBatis-Spring 整合包 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version> <!-- 對應 MyBatis 3.5+ -->
</dependency>

<!-- 連接池:Druid 推薦 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.18</version>
</dependency>

<!-- Spring 事務 & AOP -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
</dependency>
<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
</dependency>

MyBatis 配置精簡化

mybatis-config.xml 僅保留類型別名,數據源、事務管理器、Mapper 掃描全部交給 Spring 管理。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.example.demo.entity"/>
    </typeAliases>
    <!-- 移除 environments、mappers 等,全由 Spring 接管 -->
</configuration>

Spring 核心配置類(Java Config 推薦)

@Configuration
@MapperScan("com.example.demo.mapper") // 掃描 Mapper 接口
@EnableTransactionManagement // 開啟註解事務
public class MyBatisConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
            .getResources("classpath*:mapper/**/*Mapper.xml"));
        return factory.getObject();
    }

    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

Mapper 接口與 XML

// StudentMapper.java
@Repository
public interface StudentMapper {
    List selectAll();
    int insert(Student student);
    // 批量插入返回自增 ID
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertBatch(List students);
}

// StudentMapper.xml
<mapper namespace="com.example.demo.mapper.StudentMapper">
    <resultMap id="studentMap" type="Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
    </resultMap>
    
    <select id="selectAll" resultMap="studentMap">
        SELECT id, name FROM student
    </select>
    
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO student(name) VALUES(#{name})
    </insert>
</mapper>

Service 層聲明式事務

@Service
@Transactional(rollbackFor = Exception.class) // 類級別默認事務
public class StudentService {

    @Autowired
    private StudentMapper studentMapper;

    // 單表操作:繼承類級別事務
    public void addStudent(Student student) {
        studentMapper.insert(student);
    }

    // 多表事務:同一事務內操作多個 Mapper
    @Transactional // 可覆蓋傳播行為、隔離級別、超時等
    public void transferAccount(TransferDTO dto) {
        studentMapper.deductBalance(dto.getFromId(), dto.getAmount());
        studentMapper.addBalance(dto.getToId(), dto.getAmount());
        // 拋出 RuntimeException 觸發回滾
    }

    // 僅讀事務優化
    @Transactional(readOnly = true)
    public List getAllStudents() {
        return studentMapper.selectAll();
    }
}

事務傳播行為核心對比

傳播類型行為典型場景
REQUIRED (默認)有事務加入,無則新建90% 業務方法
REQUIRES_NEW掛起當前,開啟新事務日誌記錄、審計、獨立計數
NESTED嵌套事務(Savepoint)批量導入部分回滾
SUPPORTS有事務用,無則非事務純查詢方法
NOT_SUPPORTED掛起事務,以非事務運行長耗時非關鍵操作

常見坑與避坑指南

  1. @Transactional 失效:只能修飾 public 方法;內部調用(this.method())繞過代理;捕獲異常未重拋;數據源未配置事務管理器
  2. 事務不回滾:默認僅回滾 RuntimeException/Error,檢查異常需 rollbackFor = Exception.class
  3. 連接洩漏:手動獲取 SqlSession 未關閉;請始終用 Mapper 接口或 SqlSessionTemplate
  4. 多数據源:需配置多個 SqlSessionFactory、TransactionManager,並用 @Qualifier 区分

總結

MyBatis-Spring 整合核心三步:DataSource → SqlSessionFactory → TransactionManager。配合 @MapperScan、@EnableTransactionManagement、@Transactional,即可實現零侵入式聲明事務管理。生產環境務必配置連接池監控、慢 SQL 日誌、事務超時保護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved