在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx

上传人:b****2 文档编号:1202236 上传时间:2023-04-30 格式:DOCX 页数:27 大小:172.19KB
下载 相关 举报
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第1页
第1页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第2页
第2页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第3页
第3页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第4页
第4页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第5页
第5页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第6页
第6页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第7页
第7页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第8页
第8页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第9页
第9页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第10页
第10页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第11页
第11页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第12页
第12页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第13页
第13页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第14页
第14页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第15页
第15页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第16页
第16页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第17页
第17页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第18页
第18页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第19页
第19页 / 共27页
在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx

《在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx》由会员分享,可在线阅读,更多相关《在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx(27页珍藏版)》请在冰点文库上搜索。

在Spring中实现声明控制的事务管理3EclipseWord文档格式.docx

(2)面向目标实现类

当然如果没有这样的目标接口,那么Spring会使用CGLIB来解决问题,但这不是Spring所推荐的方式(此时应该设置proxyTargetClass属性为true)。

4、TransactionProxyFactoryBean类----作为DAO组件的事务代理组件

(1)作用

要进行声明控制的事务管理,一个简化的方法是使用TransactionProxyFactoryBean组件,通过它可以指定要介入的事务管理对象及其方法。

(2)定义

(3)应用的要求

TransactionProxyFactoryBean需要一个transactionManager属性,由于我们直接使用JDBC,所以在下面的示例中继续使用DataSourceTransactionManager类。

同时还需要target属性,该属性定义需要进行事务代理的类---也就是我们的DAO组件类

最后,还需要一个transactionAttributes属性,定义具体的事务要求。

在JBuilder中实现本例中的声明式的事务管理的过程

Spring声明式事务处理中由于主要使用了IoC和AOP思想,同时提供了TransactionInterceptor拦截器和常用的代理类TransactionProxyFactoryBean,从而可以允许开发者直接以配置的方式实现对组件进行事务代理。

注意:

下面的具体实现过程是在前面的代码方式的过程的基础上进行的。

因此,省略了前面的表示层和控制层的代码的实现过程的说明------具体,可以看前面的代码方式的过程。

1、添加*.jar包文件到本项目中

2、具体的实现过程----在springapp-servlet.xml文件中再增加下面的配置

(1)添加一个TransactionProxyFactoryBean的对象声明

<

beanid="

userDAOProxy"

class="

org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

>

propertyname="

proxyInterfaces"

<

list>

<

value>

springwebapp.UserLoginInterface<

/value>

/list>

<

/property>

<

transactionManager"

refbean="

/>

target"

userLoginImpleBean"

transactionAttributes"

props>

propkey="

doUpdateUserInfo*"

PROPAGATION_REQUIRED<

/prop>

*"

PROPAGATION_REQUIRED,readOnly<

/props>

/bean>

对上面的各个标签的说明:

●TransactionProxyFactoryBean是个代理类,其target属性指定要代理的对象(UserDAOProxy节点配置了一个针对userLoginImpleBean的事务代理),事务管理会自动地介入指定的方法前后。

由于工程大部分的类都要数据库操作,如果每次都要实例化这个bean(“userDAOProxy”这个bean)的话,会非常消耗资源的----Spring默认都是被管理的对象都是单例的。

●proxyInterfaces:

代理类应该实现的接口列表

●这里,我们通过transactionAttributes属性指定了事务的管理策略,doUserRegister*表示指定方法名称doUserRegister开头的都要納入事务管理,我们也可以指定方法的全名,如果在方法执行过程中发生了错误(抛出异常),則所有操作自动撤回,否則正常提交。

●doUserRegister*等方法上指定了PROPAGATION_REQUIRED,表示在目前的事务中执行操作,如果事务不存在就建立一个新的,相关的常量的含义都可以在API文件中TransactionDefinition接口中找到。

另一方面,对于其他方法(通过通配符*表示),则进行只读事务管理,以获得更好的性能----不会读取未提交的数据,同时它的数据为只读(可提高执行速度)----如可以避免对脏数据的检查。

PROPAGATION_REQUIRED,readOnly<

Spring的事务属性支持一个称为“回滚规则”的概念

默认情况下,任何RuntimeException或Error的抛出均会导致回滚。

当然,我们也可以加上多个事务的定义,中间使用逗号"

"

隔离开,例如我们可以加上只读,或者是指定某个异常产生时(并告诉事务代理,在抛出该异常时执行进行回滚),执行回滚操作。

PROPAGATION_REQUIRED,readOnly,-ExamerException

上面的这个事务策略表示某个方法将需要一个事务支持,同时当在事务过程中,如果产生了ExamerException异常,事务将会回滚。

在MyCheckedException前面加上“-”時,表示产生指定的异常时撤消操作,如果前面加上"

+"

,表示产生指定的异常时立即提交。

下面列出事务属性各个参数的含义

●PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。

这是最常见的选择。

PROPAGATION_REQUIRED等同于EJB中的TX_REQUIRED

其实现的策略为

如果我们希望服务方法一直在事务中运行,就可以使用PROPAGATION_REQUIRED。

我们使用PROPAGATION_REQUIRED的时候,如果某个TX已经在运行中,那么bean方法加入那个TX,否则Spring轻量级TX管理器将为你重新启动一个。

●PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

●PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

●PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起---这可以保证它将始终运行在一个事务中。

PROPAGATION_REQUIRES_NEW等同于EJB中的TX_REQUIRES_NEW

如果我们希望在组件服务被调用的时候,一般情况下启动新事务,那么就可以使用PROPAGATION_REQUIRES_NEW属性了。

●PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

●PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

●PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。

如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

前六个策略类似于EJBCMT中的常量名相同(请见下面的EJB中的事务的属性说明),因此,对EJB开发人员来说,应该立刻就感到熟悉。

第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。

它要求事务管理器或者使用JDBC3.0SavepointAPI提供嵌套事务行为(如Spring的DataSourceTransactionManager),或者通过JTA支持嵌套事务。

EJB中的事务的属性说明

●Nerver:

不参与事务,如果参与产生RemoteException

●NotSupported:

不能参与

●Supports:

如果调用者正在参与事务,相应的EJB调用也可以参与事务,否则不能

●Mandatory如果调用者有一个事务,相应的EJB可以参与事务,否则,TransactionRequiredException

●Required如果调用者有一个事务,相应的EJB可以参与事务,否则,容器将在调用相应的EJB之前,开始一个事务。

●当方法调用完成以后,即提交该事务。

●RequiresNew在调用相应的EJB之前,开始一个新的事务,当方法调用返回时,即提交这个事务。

嵌套事务类型(PROPAGATION_NESTED),是相对上面提到的六种情况(上面的六种应该称为平面事务类型),打个比方我现在有一个事务主要有一下几部分:

●从A用户帐户里面减去100元钱

●往B用户帐户里面添加100元钱

这样看和以前不同的事务可能没有什么区别,那我现在有点特殊的要求就是,A用户有3个帐户,B用户有2个帐户,现在我的要求就是只要再A用户的3个帐户里面任意一个减去100元,往B用户的两个帐户中任意一个里面增加100元就可以了!

一旦我们有这样的要求,那嵌套事务类型就非常适合我们的需要!

我们可以这样理解:

●将“从A用户帐户里面减去100元钱”和“往B用户帐户里面增加100元钱”我们暂时认为是一级事务操作

●将从A用户的3个帐户的任意一个帐户里面减钱看做是“从A用户帐户里面减去100元钱”这个一级事务的子事务(二级事务),同样把后面存钱的看成是另一个的二级事务。

(2)transactionManager的配置继续保留

org.springframework.jdbc.datasource.DataSourceTransactionManager"

dataSource"

3、具体的实现过程----在UserLoginController类中获得userDAOProxy,并将它转换为业务组件类的对象

(1)在我们的*.xml配置文件中删除userLoginImpleBean的属性引入,但添加对userDAOProxy的属性成员。

userLoginController"

springwebapp.UserLoginController"

commandClass"

springwebapp.UserLoginForm<

updateSuccess"

index<

updateFailure"

userLogin/updateUserInfo<

loginSuccess"

userLogin/loginSuccess<

loginFailure"

userLogin/loginFailure<

registerSuccess"

userLogin/registerSuccess<

registerFailure"

userLogin/registerFailure<

(2)因此,同样也应该在UserLoginController类中删除原来的userLoginImpleBean的get和set方法

privateUserLoginInterfaceuserLoginImpleBean=null;

publicvoidsetUserLoginImpleBean(UserLoginInterfacenewUserLoginImpleBean)

{

userLoginImpleBean=newUserLoginImpleBean;

}

publicUserLoginInterfacegetUserLoginImpleBean()

returnuserLoginImpleBean;

(3)同时再增加对userDAOProxy成员属性的get/set方法

privateUserLoginInterfaceuserDAOProxy=null;

publicUserLoginInterfacegetUserDAOProxy()

{

returnuserDAOProxy;

publicvoidsetUserDAOProxy(UserLoginInterfaceuserDAOProxy)

this.userDAOProxy=userDAOProxy;

(4)最后,在UserLoginController类的各个调度方法中直接利用userDAOProxy对象来对业务方法进行调用-----所应该注意的是,对doUserRegister和doUserLogin两个方法也应该修改。

publicModelAndViewdoUpdateUserInfo(UserLoginFormuserLoginForm)

StringuserName=userLoginForm.getUserName();

StringuserPassWord=userLoginForm.getUserPassWord();

UserInfoVOoneUserInfoVO=newUserInfoVO();

oneUserInfoVO.setUserName(userName);

oneUserInfoVO.setUserPassWord(userPassWord);

booleanokOrNot=userLoginImpleBean.doUpdateUserInfo(oneUserInfoVO);

booleanokOrNot=userDAOProxy.doUpdateUserInfo(oneUserInfoVO);

if(okOrNot)

returnnewModelAndView(this.getUpdateSuccess());

else

returnnewModelAndView(this.getUpdateFailure());

由于UserLoginImple类的userLoginImpleBean对象被userDAOProxy代理了,所以我們要作的是取得userDAOProxy,而不是userLoginImpleBean。

Spring中的事务管理实际上是基于动态AOP机制实现,为了实现动态AOP,Spring在默认情况下会使用JavaDynamicProxy,但是,DynamicProxy要求其代理的对象必须实现一个接口---本例为UserLoginInterface,该接口定义了准备进行代理的方法---本例为doUserRegister方法。

(5)控制器组件的最后代码为下面

所应该注意的是,对doUserRegister和doUserLogin两个方法也应该修改。

packagespringwebapp;

importorg.springframework.web.servlet.mvc.SimpleFormController;

importorg.springframework.web.servlet.ModelAndView;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

publicclassUserLoginControllerextendsSimpleFormController{

publicvoidsetLoginFailure(StringloginFailure){

this.loginFailure=loginFailure;

publicvoidsetLoginSuccess(StringloginSuccess){

this.loginSuccess=loginSuccess;

publicUserLoginInterfacegetUserLoginImpleBean(){

publicStringgetLoginFailure(){

returnloginFailure;

publicStringgetLoginSuccess(){

returnloginSuccess;

publicUserLoginController(){

protectedModelAndViewonSubmit(ObjectformBean)throwsException

UserLoginFormuserLoginForm=(UserLoginForm)formBean;

ModelAndViewtargetModelAndView=null;

switch(Integer.parseInt(userLoginForm.getMenuID())){

case1:

//用户登录

targetModelAndView=doUserLogin(userLoginForm);

break;

case2:

//用户注册

targetModelAndView=doUserRegister(userLoginForm);

case3:

//修改用户信息

targetModelAndView=doUpdateUserInfo(userLoginForm);

returntargetModelAndView;

booleanokOrNot=userDAOProxy.doUpdat

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2