前段時間對Spring的事務配置作了比較深刻的研究,在此之間對Spring的事務配置雖然說也配置過,可是一直沒有一個清楚的認識。經過此次的學習發覺Spring的事務配置只要把思路理清,仍是比較好掌握的。
總結以下:
Spring配置文件中關於事務配置老是由三個組成部分,分別是DataSource、TransactionManager和代理機制這三部分,不管哪一種配置方式,通常變化的只是代理機制這部分。
DataSource、TransactionManager這兩部分只是會根據數據訪問方式有所變化,好比使用Hibernate進行數據訪問時,DataSource實際爲SessionFactory,TransactionManager的實現爲 HibernateTransactionManager。
具體以下圖:
根據代理機制的不一樣,總結了五種Spring事務的配置方式,配置文件以下:
第一種方式:每一個Bean都有一個代理
<?
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:context
="http://www.springframework.org/schema/context"
xmlns:aop
="http://www.springframework.org/schema/aop"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="configLocation"
value
="classpath:hibernate.cfg.xml"
/>
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
</
bean
>
<!--
定義事務管理器(聲明式的事務)
-->
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<!--
配置DAO
-->
<
bean
id
="userDaoTarget"
class
="com.bluesky.spring.dao.UserDaoImpl"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<
bean
id
="userDao"
class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
>
<!--
配置事務管理器
-->
<
property
name
="transactionManager"
ref
="transactionManager"
/>
<
property
name
="target"
ref
="userDaoTarget"
/>
<
property
name
="proxyInterfaces"
value
="com.bluesky.spring.dao.GeneratorDao"
/>
<!--
配置事務屬性
-->
<
property
name
="transactionAttributes"
>
<
props
>
<
prop
key
="*"
>
PROPAGATION_REQUIRED
</
prop
>
</
props
>
</
property
>
</
bean
>
</
beans
>
第二種方式:全部Bean共享一個代理基類
<?
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:context
="http://www.springframework.org/schema/context"
xmlns:aop
="http://www.springframework.org/schema/aop"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="configLocation"
value
="classpath:hibernate.cfg.xml"
/>
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
</
bean
>
<!--
定義事務管理器(聲明式的事務)
-->
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<
bean
id
="transactionBase"
class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
lazy-init
="true"
abstract
="true"
>
<!--
配置事務管理器
-->
<
property
name
="transactionManager"
ref
="transactionManager"
/>
<!--
配置事務屬性
-->
<
property
name
="transactionAttributes"
>
<
props
>
<
prop
key
="*"
>
PROPAGATION_REQUIRED
</
prop
>
</
props
>
</
property
>
</
bean
>
<!--
配置DAO
-->
<
bean
id
="userDaoTarget"
class
="com.bluesky.spring.dao.UserDaoImpl"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<
bean
id
="userDao"
parent
="transactionBase"
>
<
property
name
="target"
ref
="userDaoTarget"
/>
</
bean
>
</
beans
>
第三種方式:使用攔截器
<?
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:context
="http://www.springframework.org/schema/context"
xmlns:aop
="http://www.springframework.org/schema/aop"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="configLocation"
value
="classpath:hibernate.cfg.xml"
/>
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
</
bean
>
<!--
定義事務管理器(聲明式的事務)
-->
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<
bean
id
="transactionInterceptor"
class
="org.springframework.transaction.interceptor.TransactionInterceptor"
>
<
property
name
="transactionManager"
ref
="transactionManager"
/>
<!--
配置事務屬性
-->
<
property
name
="transactionAttributes"
>
<
props
>
<
prop
key
="*"
>
PROPAGATION_REQUIRED
</
prop
>
</
props
>
</
property
>
</
bean
>
<
bean
class
="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
>
<
property
name
="beanNames"
>
<
list
>
<
value
>
*Dao
</
value
>
</
list
>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
transactionInterceptor
</
value
>
</
list
>
</
property
>
</
bean
>
<!--
配置DAO
-->
<
bean
id
="userDao"
class
="com.bluesky.spring.dao.UserDaoImpl"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
</
beans
>
第四種方式:使用tx標籤配置的攔截器
<?
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: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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>
<
context:annotation-config
/>
<
context:component-scan
base-package
="com.bluesky"
/>
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="configLocation"
value
="classpath:hibernate.cfg.xml"
/>
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
</
bean
>
<!--
定義事務管理器(聲明式的事務)
-->
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
<
tx:advice
id
="txAdvice"
transaction-manager
="transactionManager"
>
<
tx:attributes
>
<
tx:method
name
="*"
propagation
="REQUIRED"
/>
</
tx:attributes
>
</
tx:advice
>
<
aop:config
>
<
aop:pointcut
id
="interceptorPointCuts"
expression
="execution(* com.bluesky.spring.dao.*.*(..))"
/>
<
aop:advisor
advice-ref
="txAdvice"
pointcut-ref
="interceptorPointCuts"
/>
</
aop:config
>
</
beans
>
第五種方式:全註解
<?
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: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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>
<
context:annotation-config
/>
<
context:component-scan
base-package
="com.bluesky"
/>
<
tx:annotation-driven
transaction-manager
="transactionManager"
/>
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="configLocation"
value
="classpath:hibernate.cfg.xml"
/>
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
</
bean
>
<!--
定義事務管理器(聲明式的事務)
-->
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
</
beans
>
此時在DAO上需加上@Transactional註解,以下:
package
com.bluesky.spring.dao;
import
java.util.List;
import
org.hibernate.SessionFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import
org.springframework.stereotype.Component;
import
com.bluesky.spring.domain.User;
@Transactional
@Component(
"
userDao
"
)
public
class
UserDaoImpl
extends
HibernateDaoSupport
implements
UserDao {
public
List
<
User
>
listUsers() {
return
this
.getSession().createQuery(
"
from User
"
).list();
}
}