前言
在前面的小節中,我們學習了關于事務的概念以及事務管理的重要性,并且通過編程使用Spring的編程式事務管理進行操作,加深對事務管理的重要性的學習,不過,由于編程式的事務管理使用起來不是很方便,所以在日常的開發中基本不怎么使用,接下來的內容我們將學習使用Spring的聲明式事務管理,這里有一個地方需要明白的是,Spring的聲明式事務管理的實現方式其實是通過AOP的方式來實現的,也就是為原始的事務管理對象創建代理對象,從而實現事務管理增強的
基于TransactionProxyFactoryBean的事務管理配置
經過前面的學習,可以知道,Spring中配置AOP有三種方式,分別是通過ProxyFactoryBean創建代理,通過XML的方式以及通過注解的方式,既然Spring事務管理是通過AOP來實現的,那么對應的就有三種不同的方式,首先來看下基于TransactionProxyFactoryBean的管理方式
首先是Spring的配置文件
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<? 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 " xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!--開啟自動掃描--> < context:component-scan base-package = "cn.xuhuanfeng.transaction" /> <!--配置數據源,這里采用dbcp--> < bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" > < property name = "url" value = "jdbc: mysql://localhost:3306/spring " /> < property name = "driverClassName" value = "com.mysql.jdbc.Driver" /> < property name = "username" value = "root" /> < property name = "password" value = "huanfeng" /> </ bean > <!--配置JdbcTemplate--> < bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate" > <!--注入數據源--> < property name = "dataSource" ref = "dataSource" /> </ bean > <!--配置事務管理--> < bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <!--注入數據源--> < property name = "dataSource" ref = "dataSource" /> </ bean > <!--為AccountService創建代理類--> < bean id = "accountServiceProxy" class = "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" > <!--注入事務管理--> < property name = "transactionManager" ref = "transactionManager" /> <!--注入目標類,也就是所要增強的類--> < property name = "target" ref = "accountService" /> <!--配置相應的事務屬性--> < property name = "transactionAttributes" > < props > <!--指定不同的事務的處理方式 配置格式:事務傳播方式,隔離級別,readOnly,-Exception,+Exception 傳播行為是唯一必須配置的,其他的如果不配置則使用默認 -Exception表示如果發生對應的異常,則回滾事務 +Exception表示即使發生對應的異常,也依舊提交事務 --> < prop key = "transfer" >PROPAGATION_REQUIRED,ISOLATION_DEFAULT</ prop > </ props > </ property > </ bean > </ beans > |
對應的持久層代碼
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Repository public class AccountDao { @Autowired private JdbcTemplate jdbcTemplate; public void transferIn(String name, double money){ String sql = "update account set money = money + ? where name = ?" ; jdbcTemplate.update(sql, money, name); } public void transferOut(String name, double money){ String sql = "update account set money = money - ? where name = ?" ; jdbcTemplate.update(sql, money, name); } } |
業務層代碼
1
|
2
3
4
5
6
7
8
9
10
11
12
13
|
@Service public class AccountService { @Autowired private AccountDao accountDao; public void transfer( final String fromName, final String toName, final double money){ accountDao.transferOut(fromName, money); int d = 1 / 0 ; // 除0異常 accountDao.transferIn(toName, money); } } |
通過上面的配置之后,當我們在使用AccountService的時候,由于獲取的對象的代理后的對象,所以Spring會自動進行事務的監管,而我們需要做的就是配置對應的事務傳播類型以及事務管理級別等的信息,這種方式明顯對代碼以及沒有什么侵入了,但是使用這種方式意味著沒有都需要為不同的服務對象創建對應的代理對象,這其實是不太方便的,接下來我們來看下使用aop/tx命名空間來進行配置的方式。
基于aop/tx命名空間的事務管理配置
由于是對上面的業務操作進行事務管理,而且經過上一小節的學習,我們也基本熟悉了該業務,所以這里直接演示配置的代碼
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<? 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:tx = " http://www.springframework.org/schema/tx " xmlns:aop = " http://www.springframework.org/schema/aop " xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!-- 這里配置同前,故省略 --> <!--aop配置--> < aop:config > <!--配置切點--> < aop:pointcut id = "serviceMethod" expression = "execution(* cn.xuhuanfeng.transaction.AccountService.*(..))" /> <!--對應的切面--> < aop:advisor advice-ref = "txAdvice" pointcut-ref = "serviceMethod" /> </ aop:config > <!--配置事務增強--> < tx:advice id = "txAdvice" transaction-manager = "transactionManager" > < tx:attributes > <!--配置對應的事務管理,其中name為與事務相關的方法名,可以使用通配符--> < tx:method name = "transfer*" isolation = "DEFAULT" propagation = "REQUIRED" /> </ tx:attributes > </ tx:advice > </ beans > |
可以看到,通過XML配置的方式,可以更加靈活地進行事務管理
基于注解的事務管理配置
基于注解的配置方式提供了更加簡單的配置方式,只需要使用@Transactional注解進行標注,并且開啟對應的掃描即可。
1
|
2
3
4
5
6
|
// 配置相應的隔離級別、事務傳播等 @Transactional (isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED) @Service public class AccountService { // 省略其他內容 } |
Spring配置文件也相對比較簡單了
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<? 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:tx = " http://www.springframework.org/schema/tx " xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!--數據源配置等同上--> <!--通過tx命名空間,開啟主機自動掃描,并且注入事務管理器--> < tx:annotation-driven transaction-manager = "transactionManager" /> </ beans > |
可以看到,通過注解配置的方式是最簡單的配置方式,在日常的開發中,這種方式的使用的頻率也比較高
總結
本小節主要學習了Spring聲明式事務管理的配置,包括了使用TransactionProxyFactoryBean、通過aop/tx命名空間的XML配置以及基于注解的配置方式,其中,基于注解的配置方式是比較簡單的,也是使用頻率比較高的一種
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.jianshu.com/p/cf09fa4efb75