Spring4(7)——對 事務 的支持
阿新 • • 發佈:2018-10-21
持久 strong -c result fin framework ida 內部 back
1.事務
滿足一下四個條件:
- 1. 原子性;
- 2. 一致性;
- 3. 隔離性;
- 4. 持久性;
場景:轉賬 ( 成功從A轉出,但未成功轉入B ,出現業務的不一致性,需要事務回滾)
2.編程式事務管理(用的少)
- Spring 提供的事務模版類:org.springframework.transaction.support.TransactionTemplate
- 事務管理器:org.springframework.jdbc.datasource.DataSourceTransactionManager
beans.xml 事務管理器配置
<!-- jdbc事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"></property> </bean> <!-- service層註入事務管理器 --> <bean id="bankService" class="com.java1234.service.impl.BankServiceImpl"> <property name="bankDao" ref="bankDao"></property> <property name="transactionTemplate"ref="transactionTemplate"></property> </bean>
Service層
public class BankServiceImpl implements BankService{ private BankDao bankDao; private TransactionTemplate transactionTemplate; public void setBankDao(BankDao bankDao) { this.bankDao = bankDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } @Override public void transferAccounts(final int count, final int userIdA, final int userIdB) { //final // TODO Auto-generated method stub transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { //內部類 // TODO Auto-generated method stub bankDao.outMoney(count, userIdA); bankDao.inMoney(count, userIdB); } }); } }
缺點:會侵入到業務邏輯代碼中(看內部類部分)
3.聲明式事務管理(推薦使用)
使用 XML 配置聲明式事務 和 使用註解配置聲明式事務;
- 1. 使用 XML 配置聲明式事務;
命名空間加入
<!-- tx --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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/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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
配置事務通知
<!-- jdbc事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事務通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="new*" propagation="REQUIRED" /> <tx:method name="set*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="change*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="load*" propagation="REQUIRED" read-only="true" /> <tx:method name="*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <!-- 配置事務切面 --> <aop:config> <!-- 配置切點 --> <aop:pointcut id="serviceMethod" expression="execution(* com.java1234.service.*.*(..))" /> <!-- 配置事務通知 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/> </aop:config>
-
2. 使用註解配置聲明式事務;
beans.xml 中不再需要(刪除以下)
<!-- 配置事務通知 --> <!-- 配置事務切面 -->
需要加入(加入以下)
<tx:annotation-driven transaction-manager="transactionManager"/>
Service 層
@Transactional //註解 public class BankServiceImpl implements BankService{ private BankDao bankDao; public void setBankDao(BankDao bankDao) { this.bankDao = bankDao; } @Override public void transferAccounts(int count, int userIdA, int userIdB) { // TODO Auto-generated method stub // TODO Auto-generated method stub bankDao.outMoney(count, userIdA); bankDao.inMoney(count, userIdB); } }
對比:service 多時,xml配置更方便一點。
4.事務傳播行為
事務傳播行為:Spring 中,當一個 service 方法調用另外一個 service 方法的時候,因為每個 service 方法都有事務,這時候就出現了事務的嵌套;由此,就產生了事務傳播行為; 在 Spring 中,通過配置 Propagation(傳播),來定義事務傳播行為;
- PROPAGATION_REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
- PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。
- PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。
- PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。
- PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
- PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
Spring4(7)——對 事務 的支持