在Spring中实现声明控制的事务管理3Eclipse.docx

上传人:b****8 文档编号:28854687 上传时间:2023-07-20 格式:DOCX 页数:22 大小:135.96KB
下载 相关 举报
在Spring中实现声明控制的事务管理3Eclipse.docx_第1页
第1页 / 共22页
在Spring中实现声明控制的事务管理3Eclipse.docx_第2页
第2页 / 共22页
在Spring中实现声明控制的事务管理3Eclipse.docx_第3页
第3页 / 共22页
在Spring中实现声明控制的事务管理3Eclipse.docx_第4页
第4页 / 共22页
在Spring中实现声明控制的事务管理3Eclipse.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

在Spring中实现声明控制的事务管理3Eclipse.docx

《在Spring中实现声明控制的事务管理3Eclipse.docx》由会员分享,可在线阅读,更多相关《在Spring中实现声明控制的事务管理3Eclipse.docx(22页珍藏版)》请在冰豆网上搜索。

在Spring中实现声明控制的事务管理3Eclipse.docx

在Spring中实现声明控制的事务管理3Eclipse

在Eclipse中实现Spring中声明控制的事务管理

1、实现Spring的声明控制的事务管理

(1)声明控制的事务管理的实现----借助于SpringIoC和AOP

Spring提供声明控制的事务管理,这是借助于SpringIoC和AOP所提供的功能,同时提供了TransactionInterceptor拦截器和常用的代理类TransactionProxyFactoryBean,可以直接对组件进行事务代理。

(2)尽量使用声明控制的事务管理

不过现在我们不必太理会SpringAOP的编程实现,而只需要进行基本的配置,我们就可以使用声明控制的事务管理。

建议在基于SpringFramework的应用开发中,尽量使用声明控制的事务管理,以获得数据逻辑代码的最佳可读性。

(3)所需要的*.jar包文件---应该加入到系统中

Spring的事务管理依赖于aopalliance.jar与cglib-nodep-2.1_3.jar。

因此,我们必须在Web应用的lib目录下增加对aopalliance.jar(在spring-framework-1.2.6\lib\aopalliance目录内)与

对cglib-nodep-2.1_3.jar的引用(在spring-framework-1.2.6\lib\cglib目录内)。

将它们加入到我们的lib目录中

(4)优点----实现类似EJBCMT的特性

使用声明控制的事务管理的好处是,事务管理不侵入我们所开发的组件(此时,在DAO类中不再需要对TransactionManager类的对象的引入),具体来说,我们的DAO类不会意识到正在事务管理之中,而且如果我们想要改变事务管理的策略的话,也只需要在定义配置文件中重新组织即可。

2、实现的基本原理

Spring中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通Java类封装事务控制,它是通过动态代理实现的,由于接口是延迟实例化的,Spring在这段时间内通过其拦截器来加载事务管理器。

3、实现的主要形式

(1)面向目标接口

动态代理的一个重要特征是,它是针对接口的,所以我们的DAO要通过动态代理来让Spring接管事务,就必须在DAO前面抽象出一个接口并面向该目标接口。

(2)面向目标实现类

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

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

(1)作用

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

(2)定义

(3)应用的要求

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

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

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

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

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

注意:

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

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

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

最后为下面的状态

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

(1)添加transactionManager的配置

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

com.px1987.springwebapp.dao.DAOInterface

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED,readOnly

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

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

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

●proxyInterfaces:

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

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

●updateOneUserInf*等方法上指定了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元钱”这个一级事务的子事务(二级事务),同样把后面存钱的看成是另一个的二级事务。

(3)完整的配置内容为下面的状态

xmlversion="1.0"encoding="UTF-8"?

>

DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN2.0//EN"

"http:

//www.springframework.org/dtd/spring-beans-2.0.dtd">

showResult

springappController

userLoginController

userLoginController

userLoginController

org.springframework.web.servlet.view.InternalResourceView

/

.jsp

showOtherError

showDBError

showRuntimeError

net.sourceforge.jtds.jdbc.Driver

jdbc:

jtds:

sqlserver:

//localhost:

1433/WebStudyDB

sa

1234

com.px1987.springwebapp.dao.DAOInterface

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED,readOnly

3、在UserManageImple类中获得daoImpleProxy,并将它转换为DAOInterface类的对象----只需要在userManager.xml中做下面的配置修改。

4、在DAOImple类中不需要做任何附加编程

packagecom.px1987.springwebapp.dao;

importcom.px1987.springwebapp.model.UserInfoVO;

importorg.springframework.jdbc.core.*;

importjava.util.*;

publicclassDAOImpleimplementsDAOInterface

{

JdbcTemplatejdbcTemplate=null;

publicDAOImple()

{

//TODO自动生成构造函数存根

}

publicbooleandeleteOneUserInfo(intuserID)

{

//TODO自动生成方法存根

returnfalse;

}

publicbooleaninsertOneUserInfo(UserInfoVOoneUserInfoVO)

{

StringinsertStatement="insertintoUserInfovalues(?

?

?

?

?

?

?

?

)";

java.util.Datenow=newjava.util.Date();

ObjectuserInfoParameter[]={

oneUserInfoVO.getUserName(),

oneUserInfoVO.getUserPassWord(),

oneUserInfoVO.getUserDepartment(),

newInteger(oneUserInfoVO.getUserAdminLevel()),

newInteger(oneUserInfoVO.get

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

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1