Java事務的類型有三種:
JDBC事務、 可以將多個 SQL 語句結合到一個事務中。JDBC 事務的一個缺點是事務的范圍局限於一個數據庫連接。一個 JDBC 事務不能跨越多個數據庫
JTA(Java Transaction API)事務、事務可以跨越多個數據庫或多個DAO,使用也比較復雜。
容器事務。主要指的是J2EE應用服務器提供的事務管理,局限於EJB應用使用。
spring事務的配置方式編程式事務和聲明式事務,相信大家都知道是有5種,但我們經常使用的應該就是基於注解和tx標簽配置攔截器兩種方式了
1
2
3
4
5
6
7
8
9
10
|
<
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
>
|
ps:聲明式事務管理建立在AOP之上的。其本質是對方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務。
1、基於注解,DAO上需加上@Transactional注解
1
|
<
tx:annotation-driven
transaction-manager
=
"transactionManager"
/>
|
2、使用tx標簽配置的攔截器
1
2
3
4
5
6
7
8
9
10
11
12
|
<
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
>
|
3、使用攔截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<
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
>
|
4、所有Bean共享一個代理基類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<
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
>
|
5、每個Bean都有一個代理
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<
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
>
|