Spring支持編程式事務管理和聲明式的事務管理。spring
編程式事務管理數據庫
將事務管理代碼嵌到業務方法中來控制事務的提交和回滾express
缺點:必須在每一個事務操做業務邏輯中包含額外的事務管理代碼編程
聲明式事務管理
通常狀況下比編程式事務好用。app
將事務管理代碼從業務方法中分離出來,以聲明的方式來實現事務管理。框架
將事務管理做爲橫切關注點,經過aop方法模塊化。Spring中經過Spring AOP框架支持聲明式事務管理。
ide
下面是聲明式事務的兩種實現方法模塊化
根據方法名自動爲對應的方法添加事務優化
<!-- 1. 配置事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2. 配置事務屬性 --> <!--<tx:advice>元素聲明事務通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 事務管理的方法名 --> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="append*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="modify*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="repair" propagation="REQUIRED" /> <tx:method name="delAndRepair" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" /> <tx:method name="datagrid*" propagation="REQUIRED" /> <tx:method name="query*" propagation="SUPPORTS" read-only="true" /> <tx:method name="select*" propagation="SUPPORTS" read-only="true" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="load*" propagation="SUPPORTS" read-only="true" /> <tx:method name="search*" propagation="SUPPORTS" read-only="true" /> <tx:method name="count*" propagation="SUPPORTS" read-only="true" /> <tx:method name="truncate*" propagation="SUPPORTS" read-only="true" /> <tx:method name="menu*" propagation="SUPPORTS" read-only="true" /> <tx:method name="exist*" propagation="SUPPORTS" read-only="true" /> <tx:method name="exist*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <!-- 3. 配置事務切入點, 以及把事務切入點和事務屬性關聯起來 --> <aop:config> <aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" id="txPointCut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
Spring中註解的方式@Transactional標註事務方法。爲了將方法定義爲支持事務處理,能夠在方法上添加@Transactional註解。根據Spring AOP基於代理機制,只能標註公有方法。若是在類上標註@Transactional註解,那麼這個類中全部公有方法都會被定義爲支持事務。
ui
<!-- 配置事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 啓用事務註解 --> <tx:annotation-driven transaction-manager="transactionManager"/>
在方法上添加
//添加事務註解 //1.使用 propagation 指定事務的傳播行爲, 即當前的事務方法被另一個事務方法調用時 //如何使用事務, 默認取值爲 REQUIRED, 即便用調用方法的事務 //REQUIRES_NEW: 事務本身的事務, 調用的事務方法的事務被掛起. //2.使用 isolation 指定事務的隔離級別, 最經常使用的取值爲 READ_COMMITTED //3.默認狀況下 Spring 的聲明式事務對全部的運行時異常進行回滾. 也能夠經過對應的 //屬性進行設置. 一般狀況下去默認值便可. //4.使用 readOnly 指定事務是否爲只讀. 表示這個事務只讀取數據但不更新數據, //這樣能夠幫助數據庫引擎優化事務. 若真的事一個只讀取數據庫值的方法, 應設置 readOnly=true //5.使用 timeout 指定強制回滾以前事務能夠佔用的時間. @Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, noRollbackFor={UserAccountException.class}, rollbackFor = IOException.class, readOnly=false, timeout=3) @Override public void purchase(String username, String isbn) {}