Spring如何設定讓事務自動提交和回滾?Spring兩種事務管理方式的配置及使用
1,我們要明確,Spring如何設定讓事務自動提交和回滾?
①如何自動提交?
理論上,可以通過對DataSource如下設定,讓事務自動提交
- <!-- 配置資料來源 -->
- <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
- <propertyname="defaultAutoCommit"value="true"></property>
- </bean>
實際上,這個設定對於大多數資料來源是沒有必要的,例如"org.apache.commons.dbcp.BasicDataSource"
(我們可以通過反編譯外掛或者反編譯工具瀏覽該jar包),我們發現
- public BasicDataSource() {
- this.defaultAutoCommit = true;
- this.defaultReadOnly = null;
- /*此類通過無參的構造方法例項化:new BasicDataSource()*/
上述表明:該資料來源通過構造方法,初始化成員變數,defaultAutoCommit預設為true。
②如何自動回滾?
2,想要Spring對事務實現自動管理,首先我們要為資料來源配置事務管理器
SSH中配置如下:
-
- <!-- 配置資料來源 -->
- <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
- <propertyname="driverClassName"value="${jdbc_driverClassName}"></property>
- </bean>
- <!-- 配置SessionFactory -->
-
<beanid="sessionFactory"class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
- <propertyname="dataSource"ref="dataSource"/>
- </bean>
- <!-- 配置一個事務管理器 -->
- <beanid="transactionManager"
- class="org.springframework.orm.hibernate4.HibernateTransactionManager">
- <propertyname="sessionFactory"ref="sessionFactory"/>
- </bean>
- <!-- 配置資料來源 -->
- <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
- <propertyname="driverClassName"value="${jdbc_driverClassName}"></property>
- </bean>
- <!-- 配置事務管理器 -->
- <beanname="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <propertyname="dataSource"ref="dataSource"/>
- </bean>
總結:Mybatils與hibernate在事務管理配置上有差別 —— Mybatils通常使用Spring預設的資料來源事務管理器只要求相同資料來源,不做其他配置;Hibernate使用專門的Spring事務管理器需要引用具備相同資料來源的SessionFactory。
3,Spring的事務管理方式有哪幾種?如何配置並使用?(事務管理器建立完成,以它為基礎配置事務標識——用來建立並管理事務)
包含兩種: 程式設計式事務管理、宣告式事務管理
(一)其中程式設計式管理帶來程式碼冗餘,違背Spring簡潔特性,基本上很少使用,例如:
- int a=consumpDao.insert(s);//插入消費明細
- int b=customerDao.insert(customer);//此處實際應該update(customer),不然會出現重複主鍵的異常
- int d=0;
- if(a*b*d==1){
- json.put("result",0);
- json.put("msg", "購買成功");
- json.put("data", "");
- }else{
- json.put("result",-1);
- json.put("msg", "購買失敗");
- json.put("data", "");
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- }
其中使用程式TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 在沒有異常丟擲的情況下實現
注意:儘管可以採用程式設計式方法回滾事務,但“回滾”只是事務的生命週期之一,所以要麼程式設計實現事務的全部必要週期,要麼仍要
配置事務切點,即,將事務管理的其他週期交由Spring的標識!
(二)其中宣告式管理符合Spring的特性,被廣泛使用 —— 註解易於配置,配置易於程式設計 ,它的實現具有兩種常用方式:
①一種是基於tx和aop切面攔截的xml配置檔案:
- <tx:adviceid="transactionAdvice"transaction-manager="transactionManager">
- <!-- 切點攔截的位置下,所有形式類似的方法名,‘事務’都會交由相應事務管理工具管理-->
- <tx:attributes>
- <tx:methodname="insert*"propagation="REQUIRED"/>
- <tx:methodname="get*"propagation="REQUIRED"read-only="true"/>
- </tx:attributes>
- </tx:advice>
- <aop:configexpose-proxy="true">
- <aop:pointcutid="transactionPointcut"expression="execution(* com.local.*.*.*(..))"/>
- <aop:advisorpointcut-ref="transactionPointcut"advice-ref="transactionAdvice"/>
- </aop:config>
- <!-- 對所有層的事務方法進行切點攔截 *的含義:①所有返回型別 ②所有包③所有類 ④所有方法(..)標識方法內的所有引數 -->
- <aop:configexpose-proxy="true">
- <aop:pointcutid="transactionPointcut"expression="execution(* com.local.service.*.*(..))"/>
- <aop:advisorpointcut-ref="transactionPointcut"advice-ref="transactionAdvice"/>
- </aop:config>
- @RequestMapping("consump")
- publicvoid insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{
- JSONObject json =new JSONObject();
②另一種就是基於@Transactional註解:
- <!-- 註解方式配置事物 -->
- <tx:annotation-driventransaction-manager="transactionManager"/>
- @Transactional
- @RequestMapping("consump")
- publicvoid insertConsumption(Customer c,Consumption s,Mygift m) throws Exception{
- JSONObject json =new JSONObject();