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

MyBatis 事務管理詳解:獨立模式、Spring 整合、編程式、@Transactional、TransactionTemplate

     編輯:Java 相關知識

一、MyBatis 獨立模式:SqlSession 手動控制

SqlSession session = sqlSessionFactory.openSession(false); // false = 非自動提交
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    mapper.update(user1);
    mapper.update(user2);
    int i = 1 / 0; // 模擬異常
    session.commit(); // 全部成功才提交
} finally {
    session.close(); // 關閉釋放連接
}

核心:openSession(false) 開啟事務,commit()/rollback()(異常時隱式回滾),close() 釋放。

二、Spring 整合模式:DataSourceTransactionManager

1. XML 配置

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

2. 注解驅動 @Transactional

@Service
public class UserService {
    @Autowired UserMapper mapper;

    @Transactional // 默認:RuntimeException/Error 觸發回滾
    public void batchUpdate() {
        mapper.update(user1);
        int i = 1 / 0; // 拋出 RuntimeException → 事務回滾
        mapper.update(user2); // 不會執行
    }
}

注意:捕獲異常且不重新拋出會導致事務提交(框架感知不到異常)。

3. 編程式事務:TransactionTemplate

@Autowired TransactionTemplate txTemplate;

public void batchWithTemplate() {
    txTemplate.execute(status -> {
        mapper.update(user1);
        int i = 1 / 0; // 異常 → 回滾
        mapper.update(user2);
        return null;
    });
}

4. 容器管理事務 (JTA)

<tx:jta-transaction-manager/>
// 或指定 ManagedTransactionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="transactionFactoryClass" value="org.apache.ibatis.transaction.managed.ManagedTransactionFactory"/>
</bean>

三、事務傳播行為速查

傳播類型行為常用場景
REQUIRED有事務則加入,無則新建默認,大多數業務
REQUIRES_NEW掛起當前,新建獨立事務日誌記錄、獨立補償
NESTED嵌套事務(保存點)部分回滾
SUPPORTS有事務則加入,無則非事務只讀查詢
NOT_SUPPORTED掛起事務,非事務運行外部服務調用
NEVER不允許事務,拋異常嚴格非事務
MANDATORY必須在事務中,否則拋異常強制事務上下文

四、隔離級別與常見問題

隔離級別髒讀不可重複讀幻讀
READ_UNCOMMITTED✅✅✅
READ_COMMITTED❌✅✅
REPEATABLE_READ❌❌✅
SERIALIZABLE❌❌❌

MySQL InnoDB 默認 REPEATABLE_READ(通過 MVCC + Gap Lock 解決幻讀)。

五、最佳實踐清單

  • 服務層方法加 @Transactional,DAO 層不加。
  • 異常必須拋出(或 throw new RuntimeException(e)),切勿吞掉。
  • 只讀查詢加 @Transactional(readOnly = true) 優化。
  • 避免在事務中進行遠程調用、耗時運算、大量數據處理。
  • 長事務拆分:拆小業務、異步補償、Saga 模式。

結語

MyBatis 事務管理核心在於 SqlSession 生命週期與 Spring 事務抽象的結合。理解 @Transactional 底層原理(AOP 代理、ThreadLocal 綁定連接、異常攔截回滾),才能在複雜業務中正確控制事務邊界。

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