Spring
的事務處理
(零雨其蒙原創(chuàng),轉(zhuǎn)載請注明)
一、概述
(一)基本概念
1
、什么是Spring事務處理?
什么是事務處理我就不想回答了。
Spring
的事務處理,可以說是
Spring AOP
的一種實現(xiàn)。因為事務處理是所謂方面(
Aspect
)的一個子集。因此默認情況下,事務處理是利用
Java
動態(tài)代理機制實現(xiàn)的,這樣就必須先定義一個接口,然后再編寫實現(xiàn);而對于沒有接口的
Javabean
,則通過
CGLIB
實現(xiàn)。這部分是
Spring AOP
部分的內(nèi)容。
2
、兩種事務處理方式
和
EJB
一樣,
Spring
也提供兩種事務處理方式,一種是編程式事務處理;一種是聲明式事務處理。
(二)框架圖
實現(xiàn)事務處理的兩種方式
|
Java
動態(tài)代理
|
CGLIB
|
?
|
(三)何時使用什么
?????????
如果需要大量的事務處理,就用聲明式事務處理,如果很少的事務處理,就用編程式
二、詳細
?????????????
編程式事務處理與聲明式事務處理
(一)編程式事務處理
1
、使用TransactionTemplate進行事務處理(Spring進行commit和rollback)
?????????
(
1
)使用事務處理的類
?
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
?
public class bookDAO{
private DataSource dataSource;//
依賴注入
dataSource
,管理數(shù)據(jù)庫
private PlatformTransationManager transactionManager;//
依賴注入管理事務
?
public void setDataSource(DataSource dataSource){
??? this.dataSource=dataSource;
}
?
???? public void setTransactionManager(PlatformTransationManager transactionManager){
???????? this. transactionManager= transactionManager;
}
?
public int create(String msg){
??? TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
?
? //
調(diào)用
transactionTemplate
的
execute
方法進行事務管理
??? Object result=
transactionTemplate.execute
(
???? //
這是一個回調(diào)函數(shù),實現(xiàn)了
TransactionCallback
接口的
doInTransaction
方法,就是在這個方法里寫數(shù)據(jù)庫新增數(shù)據(jù)的操作
?
?
??
?
?new TransactionCallback()
{
????????? public Object doInTransaction(TransactionStatus status)
{
????????????
?//
數(shù)據(jù)庫操作代碼
????????????
?return resultObject;
?????????? }
?????? }
???
)
}
}
如果不想返回結(jié)果(
resultObject
),則可以用
TransactionCallbackWithoutResult
來實現(xiàn)
TransactionCallback
接口,代碼如下:
????
?
?new TransactionCallback
WithoutResult
()
{
????????? public Object doInTransaction
WithoutResult
(TransactionStatus status)
{
????????????
?//
數(shù)據(jù)庫操作代碼
????????????
?????????? }
?????? }
?
(
2
)配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
?"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
?
?<!—
設
定dataSource
à
?? <bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
????? <!—
使用SQL Server
數(shù)
據(jù)
庫
à
?????? <property name=”driverClassName”>
????????? <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
?????? </property>
??????? <property name=”url”>
????????? <value>jdbc:Microsoft:sqlserver://localhost:1433/stdb</value>
?????? </property>
<property name=”name”>
????????? <value>admin</value>
?????? </property>
<property name=”msg”>
????????? <value>admin</value>
?????? </property>
??? </bean>
?
??? <!—
設定
transactionManager
à
??? <bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
????
???<property name=”dataSource”>
??????????? <ref bean=”dataSource”/>
??????? </property>
??? </bean>
?
?? <!—
示例中
DAO-->
?
? <bean id=”bookDAO” class=”com.bookDAO”>
??????? <property name=”dataSource”>
??????????? <ref bean=”dataSource”/>
??????? </property>
??????? <property name=”transactionManager”>
??????????? <ref bean=”transactionManager”>
??????? </property>
?? </bean>
</beans>
??
這樣
Spring
就可以自動進行
commit
和
rollback
這兩個操作了。粉色部分是為了和
bookDAO
中的粉色部分相匹配。
2
、使用JdbcTemplate進行事務處理(硬編碼進行commit和rollback)
(
1
)使用事務處理的類
?
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
?
public class bookDAO{
private DataSource dataSource;//
依賴注入
dataSource
,管理數(shù)據(jù)庫
private PlatformTransationManager transactionManager;//
依賴注入管理事務
?
public void setDataSource(DataSource dataSource){
??? this.dataSource=dataSource;
}
?
???? public void setTransactionManager(PlatformTransationManager transactionManager){
???????? this. transactionManager= transactionManager;
}
?
public int create(String msg){
? /*? TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
????? Object result=
transactionTemplate.execute
(
????
??new TransactionCallback()
{
????????? public Object doInTransaction(TransactionStatus status)
{
?
????????????? return resultObject;
?????????? }
?????? }
??? )*/
?
//
使用下面的代碼替換上面注釋掉的部分
?
?
DefaultTransactionDefinition def
=new DefaultTransactionDefinition();
?? TransactionStatus status=transactionManager.getTransaction(def);
?? try
{
??????? JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
??????? jdbcTemplate.update(“INSERT INTO book VALUES(1,’gf’,’Mastering Spring’)”);
?? }
?? catch(DataAccessException ex)
{
????
??transactionzManager.rollback(status);
?????? throw ex;
?? }
?? finally
?? {
????
?
?transactionManager.commit(status);
?? }
}
}
(
2
)配置文件
同上
?
(
二)聲明式事務處理
(
1
)使用事務處理的類
?
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.dao.*;
?
public class bookDAO{
private DataSource dataSource;//
依賴注入
dataSource
,管理數(shù)據(jù)庫
private PlatformTransationManager transactionManager;//
依賴注入管理事務
?
public void setDataSource(DataSource dataSource){
??? this.dataSource=dataSource;
}
?
???? public void setTransactionManager(PlatformTransationManager transactionManager){
???????? this. transactionManager= transactionManager;
}
?
public int create(String msg){
?
①
/*? TransactionTemplate transactionTemplate=new TransactionTemplate(transactionManager);
????? Object result=
transactionTemplate.execute
(
????
??new TransactionCallback()
{
????????? public Object doInTransaction(TransactionStatus status)
{
?
????????????? return resultObject;
?????????? }
?????? }
??? )*/
?
②
/*? DefaultTransactionDefinition def=new DefaultTransactionDefinition();
?? TransactionStatus status=transactionManager.getTransaction(def);
?? try
{
??????? JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
??????? jdbcTemplate.update(“INSERT INTO book VALUES(1,’gf’,’Mastering Spring’)”);
?? }
?? catch(DataAccessException ex)
{
?????? transactionzManager.rollback(status);
?????? throw ex;
?? }
?
? finally
?? {
?????? transactionManager.commit(status);
?? }
*/
//
使用下面的代碼替換上面注釋掉的部分
?
??
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
??? jdbcTemplate.update(“INSERT INFO book
VALUES(1,’gf’,’Mastering Spring’)”);
/
/
與
②
相比,此段代碼省去了
commit
和
rollback
事務處理語句;與
①
相比,不必實現(xiàn)
TransactionCallback
接口
}
}
(
2
)配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
?"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
?? <!—
設
定dataSource
à
?? <bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
????? <!—
使用SQL Server
數(shù)
據(jù)
庫
à
?????? <property name=”driverClassName”>
????????? <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
?????? </property>
??????? <property name=”url”>
????????? <value>jdbc:Microsoft:sqlserver://localhost:1433/stdb</value>
?????? </property>
<property name=”name”>
????????? <value>admin</value>
?????? </property>
<property name=”msg”>
????????? <value>admin</value>
?????? </property>
??? </bean>
?
??? <!—
設定
transactionManager
à
??? <bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
??????? <property name=”dataSource”>
??????????? <ref bean=”dataSource”/>
??????? </property>
??? </bean>
?
?? <!—
示例中
DAO-->
?
? <bean id=”bookDAO” class=”com.bookDAO”>
??????? <property name=”dataSource”>
??????????? <ref bean=”dataSource”/>
??????? </property>
?
??<!—
與編程式事務處理相比,在
DAO
設置中去掉了這個屬性,把它放到了代理類中。
-
à
?
???
<!—
?? <property name=”transactionManager”>
??????????? <ref bean=”transactionManager”>
??????? </property>
-
à
?
?? </bean>
??
<!—
聲明式事務處理
-
à
?? <bean id=”bookDAOProxy” class=”org.springframework.transaction.interceptor.Transation.ProxyFactoryBean”>
??????? <property name=”transacionManager”>
??????????? <ref bean=”transacionMaganer”/>
???
????</property>
<property name=”target”>
??????????? <ref bean=”bookDAO”/>
??????? </property>
<property name=”transactionAttributes”>
??????????? <props>
??????????
????<!--
表示對
bookDAO
中的
create
方法進行事務處理,并指明當前沒有事務就新建一個(用
PROPAGATION_REQUIRED
常量來表示的)
à
??????????????? <prop key=”create
*
”>PROPAGATION_REQUIRED</prop>
??????????? </props>
??????? </property>
?
?? </bean>
</beans>
?