Spring2.0框架的事務處理有兩大類:
1 編碼式事務 , 這個不說.
2 聲明式事務 , 就說這個.
聲明式事務又有三種實現方法:
1 (第一種) 最早的方法,用TransactionProxyFactoryBean,他是一個有AOP代理功能的FactoryBean.他返回的對象有事務.
還要在spring的配置文件XML中配置,比較麻煩,不詳細說.
Xml代碼
<!-- 事務測試DAO -->
<bean id="go_TestPOAO" class="pic.dao.transaction_test.TestPOAOImpl" parent="go_POAOBase"></bean>
<!-- 事務測試DAO 聲明式事務管理 -->
<bean id="go_TestPOAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>pic.dao.transaction_test.TestPOAO</value>
</list>
</property>
<property name="target" ref="go_TestPOAO"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
2 (第二種) 使用<tx:>來實現聲明式事務 ,也要在spring的配置文件XML中配置,比較麻煩,不詳細說.
Xml代碼
<tx:advice id="">
.....
</tx:advice>
<aop:config>
.....
</aop:config>
3 (第三種) 這個方法方便,使用註解來實現聲明式事務, 下面詳細說說這個方法:
第一步:引入<tx:>命名空間 ,在spring的配置文件中修改, beans根元素裏多了三行,如下
Xml代碼<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
第二步:在spring的配置文件中修改,將所有具有@Transactional 註解的bean自動配置爲聲明式事務支持
Java代碼<!--JDBC事務管理器,根據你的情況使用不同的事務管理器,如果工程中有Hibernate,就用Hibernate的事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
<!-- 用註解來實現事務管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
第三步: 在接口或類的聲明處 ,寫一個@Transactional. 要是隻的接口上寫, 接口的實現類就會繼承下來.
接口的實現類的具體方法,還可以覆蓋類聲明處的設置.
Java代碼@Transactional
public class TestPOAOImpl extends POAOBase implements TestPOAO
{
@Transactional(isolation = Isolation.READ_COMMITTED)
public void test1()
{
String sql = "INSERT INTO sy_test (NAME,AGE) VALUES('註解趙雲',30)";
execute(sql);
sql = "INSERT INTO sy_test (NAME,AGE) VALUES('註解張飛',26)";
execute(sql);
int a = 9 / 0; //異常
sql = "INSERT INTO sy_test (NAME,AGE) VALUES('註解關羽',33)";
execute(sql);
System.out.println("走完了");
}
//execute() 方法略...
}
注意的幾點:
1 @Transactional 只能被應用到public方法上, 對於其它非public的方法,如果標記了@Transactional也不會報錯,但方法沒有事務功能.
2 默認情況下,一個有事務方法, 遇到RuntiomeException 時會回滾 . 遇到 受檢查的異常 是不會回滾 的. 要想所有異常都回滾,要加上 @Transactional( rollbackFor={Exception.class,其它異常}) .
@Transactional 的所有可選屬性如下:
屬性 | 類型 | 默認值 | 說明 |
propagation | Propagation枚舉 | REQUIRED | 事務傳播屬性 (下有說明) |
isolation | isolation枚舉 | DEFAULT | 事務隔離級別 (另有說明) |
readOnly | boolean | false | 是否只讀 |
timeout | int | -1 | 超時(秒) |
rollbackFor | Class[] | {} | 需要回滾的異常類 |
rollbackForClassName | String[] | {} | 需要回滾的異常類名 |
noRollbackFor | Class[] | {} | 不需要回滾的異常類 |
noRollbackForClassName | String[] | {} | 不需要回滾的異常類名 |
=================================================================
XML配置 聲明式事務 -- tx命名空間
採用聲明式事務
1、聲明式事務配置
* 配置SessionFactory
* 配置事務管理器
* 事務的傳播特性
* 那些類那些方法使用事務
2、編寫業務邏輯方法
* 繼承HibernateDaoSupport類,使用HibernateTemplate來持久化,HibernateTemplate是Hibernate session的封裝 * 默認的回滾是RuntimeException(包括繼承RuntimeException的子類),普通異常不回滾
* 在編寫業務邏輯方法時,最好將異常一直往上拋出,在呈現層處理(struts)
* spring的事務需要設置到業務方法上(事務邊界定義到Facade類上),不要添加到Dao上
<?xml version= "1.0" encoding= "UTF-8" ?>
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 配置SessionFactory -->
<bean id="sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name="configLocation" value= "classpath:hibernate.cfg.xml" />
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionMgr" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" >
<property name="sessionFactory" >
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 配置事務傳播特性 -->
<tx:advice id="txAdvice" transaction-manager= "transactionMgr" >
<tx:attributes>
<tx:method name="add*" propagation= "REQUIRED" />
<tx:method name="del*" propagation= "REQUIRED" />
<tx:method name="update*" propagation= "REQUIRED" />
<tx:method name="*" read-only= "true" />
</tx:attributes>
</tx:advice>
<!-- 那些類使用事務 -->
<aop:config>
<aop:pointcut id="point-cut" expression= "execution(* com.wlh.spring.manager.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref= "point-cut" />
</aop:config>
</beans>