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

Spring JDBC 事務管理全解析:編程式與聲明式、PlatformTransactionManager 體系

     編輯:Java 相關知識

事務四大特性 (ACID) 速記

  • Atomicity:全成全敗
  • Consistency:約束不違反
  • Isolation:併發隔離
  • Durability:持久落盤

Spring 事務抽象核心:PlatformTransactionManager

public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition);
    void commit(TransactionStatus status);
    void rollback(TransactionStatus status);
}

主流實現:

  • DataSourceTransactionManager(JDBC/MyBatis)
  • HibernateTransactionManager
  • JtaTransactionManager(分佈式/JTA)
  • JdoTransactionManager

編程式事務:兩種寫法

1. 直接用 TransactionManager

DataSourceTransactionManager tm = new DataSourceTransactionManager(dataSource);
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = tm.getTransaction(def);
try {
    jdbcTemplate.update("INSERT ...");
    jdbcTemplate.update("INSERT ... 故意寫錯 SQL");
    tm.commit(status);
} catch (DataAccessException e) {
    tm.rollback(status);
    throw e;
}

2. TransactionTemplate(推薦,模板模式)

TransactionTemplate template = new TransactionTemplate(tm);
template.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        jdbcTemplate.update("INSERT ...");
        // 異常自動回滾,正常自動提交
    }
});

聲明式事務:AOP 代理,零侵入

方式一:TransactionProxyFactoryBean (Spring 1.x 風格)

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDAO" class="com.example.UserDAO">
  <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="target" ref="userDAO"/>
  <property name="transactionManager" ref="txManager"/>
  <property name="transactionAttributes">
    <props>
      <prop key="insert*">PROPAGATION_REQUIRED</prop>
      <prop key="update*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
      <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
  </property>
</bean>

使用時注入 userDAOProxy 而非 userDAO。

方式二:TransactionInterceptor + ProxyFactoryBean (更靈活)

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <property name="transactionManager" ref="txManager"/>
  <property name="transactionAttributes">
    <props>
      <prop key="com.example.UserDAO.insert*">PROPAGATION_REQUIRED</prop>
    </props>
  </property>
</bean>
<bean id="userDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target" ref="userDAO"/>
  <property name="interceptorNames"><list><value>txInterceptor</value></list></property>
  <property name="proxyInterfaces"><value>com.example.IUserDAO</value></property>
</bean>

此時直接注入 userDAO(被代理後),配置與業務代碼完全分離。

關鍵屬性解讀

  • PROPAGATION_REQUIRED:有事務加入,無則新建(最常用)。
  • readOnly:優化提示,適用於唯讀查詢。
  • -Exception:遇到該檢查型異常回滾;+Exception:遇到該異常提交。
  • 默認只回滾 RuntimeException / Error。

聲明式事務是 Spring 最迷人特性之一:事務邊界集中配置,業務代碼純淨無污染,切換策略只改 XML/註解。

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