在Spring中实现编程式的事务管理.doc_第1页
在Spring中实现编程式的事务管理.doc_第2页
在Spring中实现编程式的事务管理.doc_第3页
在Spring中实现编程式的事务管理.doc_第4页
在Spring中实现编程式的事务管理.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在Spring中实现编程式的事务管理1、编程式的事务管理实现-传统的JDBC事务管理(1)对每个请求都是从数据源中重新取出一个连接以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源DataSource是线程安全的,而数据连接对象Connection不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。一般的数据源由容器进行管理,包括连接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。(2)JDBC标准的事务管理实现的代码Connection conn = null;tryconn = DBConnectionFactory.getConnection;conn.setAutoCommit(false); /(1) 缺省方式是自动提交/完成对数据库的修改操作Umit(); /(2)自己提交catch(Exception e)conn.rollback(); /(3) 恢复修改/do sthfinallytryconn.close();catch(SQLException se) /do sth (3)JDBC标准的事务管理实现的代码的缺点按照以往的思路来写代码,不仅代码量比较长,而且也很容易疏忽或者忘掉一些try/catch语句,引发一些异常无法catch,因此,我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常。2、Spring JdbcTemplate的缺省的事务管理模式(1)Spring为我们对JDBC事务管理模式进行包装,从而在一定的程度上简化了编程Spring提供了几个关于事务处理的类: l TransactionDefinition /事务属性定义l TranscationStatus /代表了当前的事务,可以提交,回滚。l PlatformTransactionManager 这些类是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。(2)JdbcTemplate的缺省的事务管理模式采用的是JDBC默认的AutoCommit模式前面的例中的JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效)。如下面的操作:JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);jdbcTemplate.update(UPDATE user SET age = 10 WHERE id = 1234);jdbcTemplate.update(UPDATE user SET age = age+1 WHERE id = 1234);由于采用了AutoCommit模式,第一个update操作完成之后被自动提交,数据库中1234对应的记录已经被更新,如果第二个操作失败,我们无法使得整个事务回滚到最初状态。对于这个例子也许无关紧要,但是对于一个金融帐务系统而言,这样的问题将导致致命错误。为了实现数据操作的原子性,我们需要在程序中引入事务逻辑。(3)利用DataSourceTransactionManager类实现代码控制的事务管理org.springframework.jdbc.datasource.DataSourceTransactionManager类为JDBC DataSource类型的数据源的事务管理组件。只需要在Bean的定义配置的*.xml文件中对它进行配置,然后将其引入到我们的DAO类中。(4)使用Spring 编程式的事务管理的基本流程l 声明数据源l 声明一个事务管理类,例如DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager等l 在我们的代码中加入事务处理代码(5)代码示例如下:TransactionDefinition td = new TransactionDefinition();TransactionStatus status = transactionManager.getTransaction(td);tryJdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);jdbcTemplate.update(UPDATE user SET age = 10 WHERE id = 1234);jdbcTemplate.update(UPDATE user SET age = age+1 WHERE id = 1234);transactionMmit(status);catch(Exception e)transactionManager.rollback(status);在JBuilder中的本Project中实现Spring的代码控制的事务管理1、问题:在本项目中再添加一个对用户信息进行修改的功能模块2、添加一个updateUserInfo.jsp 在该页面中添加一个表单updateUserInfo 请输入用户名称: 请输入用户密码:3、修改我们的控制器程序,在其中增加下面的代码(黑体部分)package springwebapp;import org.springframework.web.servlet.mvc.SimpleFormController;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class UserLoginController extends SimpleFormController private UserLoginInterface userLoginImpleBean = null; public void setUserLoginImpleBean(UserLoginInterface newUserLoginImpleBean) userLoginImpleBean = newUserLoginImpleBean; public void setLoginFailure(String loginFailure) this.loginFailure = loginFailure; public void setLoginSuccess(String loginSuccess) this.loginSuccess = loginSuccess; public UserLoginInterface getUserLoginImpleBean() return userLoginImpleBean; public String getLoginFailure() return loginFailure; public String getLoginSuccess() return loginSuccess; public UserLoginController() protected ModelAndView onSubmit(Object formBean) throws Exception UserLoginForm userLoginForm = (UserLoginForm) formBean; ModelAndView targetModelAndView = null; switch (Integer.parseInt(userLoginForm.getMenuID() case 1: /用户登录 targetModelAndView = doUserLogin(userLoginForm); break; case 2: /用户注册 targetModelAndView = doUserRegister(userLoginForm); break; case 3: /修改用户信息 targetModelAndView = doUpdateUserInfo(userLoginForm); break; return targetModelAndView; public ModelAndView doUpdateUserInfo(UserLoginForm userLoginForm) String userName = userLoginForm.getUserName(); String userPassWord = userLoginForm.getUserPassWord(); UserInfoVO oneUserInfoVO = new UserInfoVO(); oneUserInfoVO.setUserName(userName); oneUserInfoVO.setUserPassWord(userPassWord); boolean okOrNot = userLoginImpleBean.doUpdateUserInfo(oneUserInfoVO); if (okOrNot) return new ModelAndView(this.getUpdateSuccess(); else return new ModelAndView(this.getUpdateFailure(); public ModelAndView doUserRegister(UserLoginForm userLoginForm) java.util.Date rightNow = new java.util.Date(); String registerTime = rightNow.toLocaleString(); UserInfoVO userInfo = new UserInfoVO(); userInfo.setUserName( userLoginForm.getUserName(); userInfo.setUserPassWord(userLoginForm.getUserPassWord(); userInfo.setUserDepartment( userLoginForm.getUserDepartment(); userInfo.setUserAdminLevel(Integer.parseInt(userLoginForm.getUserAdminLevel(); userInfo.setDepartAdminLevel(Integer.parseInt(userLoginForm.getUserAdminLevel(); userInfo.setUserImage(userLoginForm.getUserImage(); userInfo.setRegisterTime(registerTime); boolean okOrNot = userLoginImpleBean.doUserRegister(userInfo); if (okOrNot) return new ModelAndView(registerSuccess); else return new ModelAndView(registerFailure); public ModelAndView doUserLogin(UserLoginForm userLoginForm) String userName = userLoginForm.getUserName(); String userPassWord = userLoginForm.getUserPassWord(); UserInfoVO oneUserInfoVO = new UserInfoVO(); oneUserInfoVO.setUserName(userName); oneUserInfoVO.setUserPassWord(userPassWord); boolean okOrNot = userLoginImpleBean.doUserLogin(oneUserInfoVO); if (okOrNot) return new ModelAndView(getLoginSuccess(); else return new ModelAndView(getLoginFailure(); private String updateSuccess; private String updateFailure; public String getUpdateFailure() return updateFailure; public String getUpdateSuccess() return updateSuccess; public void setUpdateSuccess(String updateSuccess) this.updateSuccess = updateSuccess; public void setUpdateFailure(String updateFailure) this.updateFailure = updateFailure; private String registerSuccess; private String registerFailure; public String getRegisterSuccess() return registerSuccess; public void setRegisterSuccess(String registerSuccess) this.registerSuccess = registerSuccess; public String getRegisterFailure() return registerFailure; public void setRegisterFailure(String registerFailure) this.registerFailure = registerFailure; private String loginSuccess; private String loginFailure;4、修改我们的业务层组件(1)修改我们的业务接口以增加新的方法定义package springwebapp;public interface UserLoginInterface public abstract boolean doUserLogin(UserInfoVO oneUserInfo); public abstract boolean doUserRegister(UserInfoVO oneUserInfo); public abstract boolean doUpdateUserInfo(UserInfoVO oneUserInfo); (2)修改我们的业务实现类以增加对该方法的具体实现-修改用户的信息并采用事务来加以控制在该类中添加一个transactionManager属性,并且实现我们的带事务处理的方法-事务管理的控制最好应该放到商业逻辑层。我们可以设计一个处理商业逻辑的JavaBean,在该JavaBean中调用DAO,然后把实现商业逻辑的JavaBean的方法纳入Spring的事务管理。package springwebapp;import org.springframework.context.ApplicationListener;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ApplicationContext;import org.springframework.beans.BeansException;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.transaction.support.DefaultTransactionDefinition;import org.springframework.transaction.TransactionStatus;import org.springframework.dao.DataAccessException;import org.springframework.transaction.PlatformTransactionManager;public class UserLoginImple implements UserLoginInterface,ApplicationContextAware ApplicationListener actionEventResponse = null; public void setActionEventResponse(ApplicationListener actionEventResponse) this.actionEventResponse = actionEventResponse; private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) this.jdbcTemplate = jdbcTemplate; private PlatformTransactionManager transactionManager; public void setTransactionManager(PlatformTransactionManager transactionManager) this.transactionManager = transactionManager; public UserLoginImple() public boolean doUserRegister(UserInfoVO userInfo) return true; public boolean doUpdateUserInfo(UserInfoVO oneUserInfo) String userName=oneUserInfo.getUserName(); String userPassWord=oneUserInfo.getUserPassWord(); Object parameter=userPassWord,userName; /我们需要事务定义,作为示例,我们采用DefaultTransactionDefinition DefaultTransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def); String updateSQL1 = update userInfo set userPassWord = ? where userName =?; String updateSQL2 = update userInfo1 set userPassWord = ? where userName =?; try this.jdbcTemplate.update(updateSQL1,parameter); this.jdbcTemplate.update(updateSQL2,parameter);/* 为了说明事务处理,我们对数据库表进行了两次修改,其中第二次修改应该是失败的(并注意到我們故意在数据库表名称上写错, 这使得SQL句子不合语法,因而造成DataAccessException(它封裝了SQLException), 这个异常被catch捕捉,因而执行rollback()取消前面的正确执行SQL的操作结果,如果沒有发生错误, 则最后我们使用commit()来提交操作。*/ catch (DataAccessException ex) transactionManager.rollback(status); / 也可以执行status.setRollbackOnly(); throw ex; transactionMmit(status); return true; public boolean doUserLogin(UserInfoVO oneUserInfo) boolean okOrNot=false; String userName=oneUserInfo.getUserName(); String userPassWord=oneUserInfo.getUserPassWord(); String sqlStatement=select * from UserInfo where userName=+userName+ and userPassWord =+userPassWord+; java.util.List resultRows = jdbcTemplate.queryForList(sqlStatement); if (resultRows!=null)&(resultRows.size() != 0) /现在已经对对数据库表的访问 UserLoginActionEvent userLoginActionEvent = new UserLoginActionEvent(actionEventResponse); /注意指定事件的目标对象 this.applicationContext.publishEvent(userLoginActionEvent); /触发事件 okOrNot=true; else okOrNot=false; return okOrNot; private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException this.applicationContext = applicationContext; 5、修改我们的*.xml配置文件(1)在springapp-servlet.xml文件中添加下面的与事务相关的一些配置项目 (2)修改我们的业务实现类的对象声明 (3)修改我们的控制层组件以增加下面的属性 springwebapp.UserLoginForm index userLogin/updateUserInfo userLogin/loginSuccess userLogin/loginFailure userLogin/registerSuccess userLogin/registerFailure (4)对我们的userloginController加以声明 springappController userloginController userloginController userloginController 6、执行该程序,观察数据库表中的数据是否被修改了!(1)观察数据库表中的用户密码(2)执行本应用输入用户名称为admin,但是密码为12345678。(3)将出现下面的错误(4)同时在数据库表中的数据并没有被修改(5)将代码中的String updateSQL2 = update userInfo1 set userPassWord = ? where userName =?;中的数据库表名称由“userInfo1”改变为正确的“userInfo”,再执行本应用,将能够正确地对用户的密码进行修改。采用TransactionTemplate类来简化操作1、TransactionTemplate类TransactionTemplate封装了事务管理的功能,包括异常时的事务回滚,以及操作成功后的事务提交。和JdbcTemplate一样,它使得我们无需在琐碎的try/catch/finally代码中徘徊-也就是为我们省去了部分事务提交、回滚代码。2、修改原来的doUpdateUserInfo方法public boolean doUpdateUserInfo(UserInfoVO oneUserInfo) String userName=oneUserInfo.getUserName(); String userPassWord=oneUserInfo.getUserPassWord(); Object parameter=userPassWord,userName; TransactionTemplate transactionTemplate = ne

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论