概述
所謂編程式事務指的是通過編碼方式實現事務,即類似於JDBC編程實現事務管理。管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。
案例
使用編程事務實現手動事務
使用編程事務實現,手動事務 begin、commit、rollback
@Component public class TransactionUtils {
@Autowired private DataSourceTransactionManager dataSourceTransactionManager;
// 開啓事務 public TransactionStatus begin() { TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute()); return transaction; }
// 提交事務 public void commit(TransactionStatus transactionStatus) { dataSourceTransactionManager.commit(transactionStatus); }
// 回滾事務 public void rollback(TransactionStatus transactionStatus) { dataSourceTransactionManager.rollback(transactionStatus); } }
@Service public class UserService { @Autowired private UserDao userDao; @Autowired private TransactionUtils transactionUtils;
public void add() { TransactionStatus transactionStatus = null; try { transactionStatus = transactionUtils.begin(); userDao.add("zhangsan", 27); int i = 1 / 0; System.out.println("我是add方法"); userDao.add("lisi", 16); transactionUtils.commit(transactionStatus); } catch (Exception e) { e.printStackTrace(); } finally { if (transactionStatus != null) { transactionStatus.rollbackToSavepoint(transactionStatus); } }
}
} |
AOP技術封裝手動事務
@Component @Aspect public class AopTransaction { @Autowired private TransactionUtils transactionUtils;
// // 異常通知 @AfterThrowing("execution(* com.haha.service.UserService.add(..))") public void afterThrowing() { System.out.println("程序已經回滾"); // 獲取程序當前事務 進行回滾 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); }
// 環繞通知 @Around("execution(* com.haha.service.UserService.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("開啓事務"); TransactionStatus begin = transactionUtils.begin(); proceedingJoinPoint.proceed(); transactionUtils.commit(begin); System.out.println("提交事務"); }
} |
使用事務注意事項
事務是程序運行如果沒有錯誤,會自動提交事物,如果程序運行發生異常,則會自動回滾。
如果使用了try捕獲異常時.一定要在catch裏面手動回滾。
事務手動回滾代碼
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
聲明事務實現
概述
管理建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前創建或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。聲明式事務最大的優點就是不需要通過編程的方式管理事務,這樣就不需要在業務邏輯代碼中摻雜事務管理的代碼,只需在配置文件中做相關的事務規則聲明(或通過基於@Transactional註解的方式),便可以將事務規則應用到業務邏輯中。
顯然聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式。
聲明式事務管理使業務代碼不受污染,一個普通的POJO對象,只要加上註解就可以獲得完全的事務支持。和編程式事務相比,聲明式事務唯一不足地方是,後者的最細粒度只能作用到方法級別,無法做到像編程式事務那樣可以作用到代碼塊級別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進行事務管理的代碼塊獨立爲方法等等。
XML實現聲明
註解版本聲明
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 開啓註解 --> <context:component-scan base-package="com.haha"></context:component-scan> <!-- 1. 數據源對象: C3P0連接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean>
<!-- 2. JdbcTemplate工具類實例 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
<!-- 配置事物 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 開啓註解事物 --> <tx:annotation-driven transaction-manager="dataSourceTransactionManager" /> </beans> |
用法
@Transactional public void add() { userDao.add("wangmazi", 27); int i = 1 / 0; System.out.println("我是add方法"); userDao.add("zhangsan", 16); } |