搜档网
当前位置:搜档网 › 通过实例跟我学Spring从入门到精通——在Spring框架中实现编程式事务管理的应用实例(Eclipse版本第1部分)

通过实例跟我学Spring从入门到精通——在Spring框架中实现编程式事务管理的应用实例(Eclipse版本第1部分)

通过实例跟我学Spring从入门到精通——在Spring框架中实现编程式事务管理的应用实例(Eclipse版本第1部分)
通过实例跟我学Spring从入门到精通——在Spring框架中实现编程式事务管理的应用实例(Eclipse版本第1部分)

1.1在Spring框架中实现编程式的事务管理的应用实例(Eclipse版本第1部分)

1.1.1传统的JDBC事务管理相关的应用技术

1、编程式的事务管理实现----传统的JDBC事务管理

(1)对每个请求都是从数据源中重新取出一个连接

以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源DataSource是线程安全的,而数据连接对象Connection不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。

一般的数据源由容器进行管理,包括连接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。

(2)JDBC标准的事务管理实现的代码

Connection conn = null;

try

{

conn = DBConnectionFactory.getConnection;

conn.setAutoCommit(false); //(1) 缺省方式是自动提交

//完成对数据库的修改操作

Update

update

https://www.sodocs.net/doc/e2705297.html,mit(); //(2)自己提交

}

catch(Exception e)

{

conn.rollback(); //(3) 恢复修改

//do sth

}

finally

{

try

{

conn.close();

}

catch(SQLException se)

{

//do sth

}

}

(3)JDBC标准的事务管理实现的代码的缺点

按照以往的思路来写代码,不仅代码量比较长,而且也很容易疏忽或者忘掉一些try/catch语句,引发一些异常无法catch,因此,我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常。

2、Spring JdbcTemplate的缺省的事务管理模式

(1)Spring为我们对JDBC事务管理模式进行包装,从而在一定的程度上简化了编程Spring提供了几个关于事务处理的类:

1)TransactionDefinition //事务属性定义

2)TranscationStatus //代表了当前的事务,可以提交,回滚。

3)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 编程式的事务管理的基本流程

1)声明数据源

2)声明一个事务管理类,例如

DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager

3)在我们的代码中加入事务处理代码

(5)代码示例如下

TransactionDefinition td = new TransactionDefinition();

TransactionStatus status = transactionManager.getTransaction(td);

try

{

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'");

https://www.sodocs.net/doc/e2705297.html,mit(status);

}

catch(Exception e)

{

transactionManager.rollback(status);

}

1.1.2在Eclipse中的本Project中实现Spring的代码控制的事务管理

1、问题:什么场合需要考虑“事务”支持

在本项目中再添加一个对用户信息进行修改的功能模块。

2、添加一个updateUserInfo.jsp

(1)添加一个updateUserInfo.jsp页面文件

(2)在该页面中添加一个表单

(3)updateUserInfo.jsp页面文件中相关的HTML代码

<%@ page contentType="text/html; charset=GBK" %>

updateUserInfo

请输入用户名称:

请输入原始的用户密码:

请输入新的用户密码:

3、修改我们的UserLoginForm类增加一个,并且为它提供 get/set方法

private String newUserPassWord;

4、修改控制器程序,在其中增加下面的代码(黑体部分)

package com.px1987.springwebapp.control;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.SimpleFormController;

import com.px1987.springwebapp.model.*;

import com.px1987.springwebapp.view.*;

public class UserManageController extends SimpleFormController

{

private String loginSuccess;

private String loginFailure;

private UserManageInterface userLoginImpleBean=null;

@Override

protected ModelAndView onSubmit(Object loginFormBean) throws Exception {

UserLoginForm userFormBean=(UserLoginForm)loginFormBean;

String menuID=userFormBean.getMenuID();

ModelAndView oneModelAndView=null;

switch(Integer.parseInt(menuID))

{

case 1: //login

oneModelAndView=doUserLogin(userFormBean );

break;

case 2: //Register

oneModelAndView=doUserRegister(userFormBean );

break;

case 3: //修改用户信息

oneModelAndView = doUpdateUserInfo(userFormBean);

break;

}

throw new Exception(); //未实现声明的异常

// return oneModelAndView;

}

public ModelAndView doUpdateUserInfo(UserLoginForm userLoginForm) {

String userName = userLoginForm.getUserName();

String userPassWord = userLoginForm.getUserPassWord();

String newUserPassWord = userLoginForm.getNewUserPassWord();

UserInfoVO oneUserInfoVO = new UserInfoVO();

oneUserInfoVO.setUserName(userName);

oneUserInfoVO.setUserPassWord(userPassWord);

boolean okOrNot = userLoginImpleBean.doUpdateUserInfo(oneUserInfoVO,newUserPassWord);

if (okOrNot)

{

return new ModelAndView(this.getUpdateSuccess());

}

else

{

return new ModelAndView(this.getUpdateFailure());

}

}

public ModelAndView doUserLogin(UserLoginForm userLoginForm )

{

// (1)获得请求参数

String userName=userLoginForm.getUserName();

String userPassWord=userLoginForm.getUserPassWord();

// (2)对业务功能组件进行调用以完成指定的功能实现

UserInfoVO oneUserInfoVO=new UserInfoVO();

oneUserInfoVO.setUserName(userName);

oneUserInfoVO.setUserPassWord(userPassWord);

boolean okOrNot=userLoginImpleBean.doUserLogin(oneUserInfoVO);

// (3)对业务功能组件处理后的结果进行调度

if(okOrNot)

{

return new ModelAndView(loginSuccess);

}

else

{

return new ModelAndView(loginFailure);

}

}

public ModelAndView doUserRegister(UserLoginForm userRegisterForm )

{

java.util.Date rightNow = new java.util.Date();

String registerTime = rightNow.toLocaleString();

UserInfoVO userInfo = new UserInfoVO();

userInfo.setUserName(userRegisterForm.getUserName());

userInfo.setUserPassWord(userRegisterForm.getUserPassWord());

userInfo.setUserDepartment( userRegisterForm.getUserDepartment()); userInfo.setUserAdminLevel(Integer.parseInt(userRegisterForm.getUserAdminLevel ()));

userInfo.setDepartAdminLevel(Integer.parseInt(userRegisterForm.getUserAdminLev el()));

userInfo.setUserImage(userRegisterForm.getUserImage());

userInfo.setRegisterTime(registerTime);

boolean okOrNot= userLoginImpleBean.doUserRegister(userInfo);

if(okOrNot){

return new ModelAndView(registerSuccess);

}

else{

return new ModelAndView(registerFailure);

}

}

public UserManageController(){

}

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;

}

public String getLoginFailure() {

return loginFailure;

}

public void setLoginFailure(String loginFailure) {

this.loginFailure = loginFailure;

}

public String getLoginSuccess() {

return loginSuccess;

}

public void setLoginSuccess(String loginSuccess) {

this.loginSuccess = loginSuccess;

}

public void setUserLoginImpleBean(UserManageInterface userLoginImpleBean) { https://www.sodocs.net/doc/e2705297.html,erLoginImpleBean = userLoginImpleBean;

}

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;

}

}

5、修改示例中的业务层组件

(1)修改我们的业务接口以增加新的方法定义

package com.px1987.springwebapp.model;

public interface UserManageInterface

{

public abstract boolean doUserLogin(UserInfoVO oneUserInfo);

public abstract boolean doUserRegister(UserInfoVO oneUserInfo);

public boolean doUpdateUserInfo(UserInfoVO userInfo ,String newUserPassWord);

}

(2)修改我们的业务实现类以增加对该方法的具体实现

package com.px1987.springwebapp.model;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationListener;

import org.springframework.context.ApplicationContextAware;

import com.px1987.springwebapp.event.*;

import com.px1987.springwebapp.dao.*;

public class UserManageImple implements UserManageInterface,ApplicationContextAware

{

private DAOInterface daoImpleObject=null;

private ApplicationContext applicationContext;

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException

{

this.applicationContext = applicationContext;

}

ApplicationListener actionEventResponse=null; //代表事件响应者

public void setActionEventResponse(ApplicationListener actionEventResponse)

{

this.actionEventResponse = actionEventResponse;

}

public UserManageImple() {

}

public boolean doUpdateUserInfo(UserInfoVO oneUserInfoVO ,String newUserPassWord)

{

boolean okOrNot=false;

okOrNot=daoImpleObject.updateOneUserInfo(oneUserInfoVO,

newUserPassWord);

return okOrNot;

}

public boolean doUserRegister(UserInfoVO userInfo )

{

boolean okOrNot=daoImpleObject.insertOneUserInfo(userInfo);

if(okOrNot)

{

UserLoginActionEvent userLoginActionEvent = new UserLoginActionEvent(actionEventResponse); //注意指定事件的目标对象 this.applicationContext.publishEvent(userLoginActionEvent); //触发事件

}

return okOrNot;

}

public boolean doUserLogin(UserInfoVO oneUserInfo) //“业务处理”

{

boolean okOrNot=false;

String userName=oneUserInfo.getUserName();

String userPassWord=oneUserInfo.getUserPassWord();

UserInfoVO returnOneUserInfo=daoImpleObject.selectUserInfo(userName, userPassWord);

if(returnOneUserInfo==null)

{

okOrNot=false;

}

else

{

okOrNot=true;

}

return okOrNot;

}

public void setDaoImpleObject(DAOInterface daoImpleObject) {

this.daoImpleObject = daoImpleObject;

}

}

6、修改示例DAO中的各个组件

(1)修改DAO的接口DAOInterface,并增加一个方法的定义

package com.px1987.springwebapp.dao;

import com.px1987.springwebapp.model.*;

public interface DAOInterface

{

public UserInfoVO selectUserInfo(String userName, String userPassWord);

public boolean insertOneUserInfo(UserInfoVO oneUserInfoVO);

public boolean deleteOneUserInfo(int userID);

public boolean updateOneUserInfo(UserInfoVO oneUserInfoVO);

public boolean updateOneUserInfo(UserInfoVO oneUserInfoVO,String newUserPassWord);

}

(2)修改我们的接口DAOInterface实现类以增加对该方法的具体实现

package com.px1987.springwebapp.dao;

import https://www.sodocs.net/doc/e2705297.html,erInfoVO;

import org.springframework.jdbc.core.*;

import java.util.*;

public class DAOImple implements DAOInterface

{

JdbcTemplate jdbcTemplate=null;

public DAOImple(){

}

public boolean deleteOneUserInfo(int userID)

{

return false;

}

public boolean insertOneUserInfo(UserInfoVO oneUserInfoVO) {

String insertStatement="insert into UserInfo values(?,?,?,?,?,?,?,?)";

java.util.Date now=new java.util.Date();

Object userInfoParameter[]={

oneUserInfoVO.getUserName(),

oneUserInfoVO.getUserPassWord(),

oneUserInfoVO.getUserDepartment(), new

Integer(oneUserInfoVO.getUserAdminLevel()),

new

Integer(oneUserInfoVO.getDepartAdminLevel()),

oneUserInfoVO.getUserImage(),

oneUserInfoVO.getRegisterTime(),

new Integer((int)now.getTime())

};

boolean okOrNot=false;

int

returnCount=jdbcTemplate.update(insertStatement,userInfoParameter);

if(returnCount!=0)

{

okOrNot=true;

}

else

{

okOrNot=false;

}

return okOrNot;

}

public UserInfoVO selectUserInfo(String userName, String userPassWord) {

UserInfoVO oneUserInfoVO=null;

// String sqlStatement="select * from UserInfo where userName='"+userName+"' and userPassWord ='"+ userPassWord+"'";

String sqlStatement="select * from UserInfo where userName=? and userPassWord =?";

Object userInfoPara[]={ userName,

userPassWord

};

java.util.List resultRows = jdbcTemplate.queryForList(sqlStatement,userInfoPara);

if ((resultRows!=null)&&(resultRows.size() != 0)) //现在已经对对数据库表的访问

{

Map oneUserMap = (Map) resultRows.get(0);

String returnUserName=(String)oneUserMap.get("userName");

String returnUserPassWord=(String)oneUserMap.get("userPassWord");

oneUserInfoVO=new UserInfoVO();

oneUserInfoVO.setUserName(returnUserName);

oneUserInfoVO.setUserPassWord(returnUserPassWord)

}

else

{

oneUserInfoVO=null;

}

return oneUserInfoVO;

}

public boolean updateOneUserInfo(UserInfoVO oneUserInfoVO)

{

return false;

}

public boolean updateOneUserInfo(UserInfoVO oneUserInfoVO,String newUserPassWord){

String userName=oneUserInfoVO.getUserName();

String userPassWord=oneUserInfoVO.getUserPassWord();

Object parameter[]={newUserPassWord,userName,userPassWord};

String updateSQL1 = "update userInfo set userPassWord = ? where userName =? and userPassWord=?";

this.jdbcTemplate.update(updateSQL1,parameter);

return true;

}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this.jdbcTemplate = jdbcTemplate;

}

}

7、再增加另外两个页面——updateSuccess.jsp代表修改成功的提示结果信息的页面(1)增加updateSuccess.jsp页面

(2)updateSuccess.jsp页面内的HTML标签的内容如下

<%@ page contentType="text/html; charset=GBK" %>

loginSuccess

您的密码被成功修改

8、再增加另外两个页面——updateFailure.jsp代表修改失败的提示结果信息的页面(1)增加updateFailure.jsp页面

(2)updateFailure.jsp页面内的HTML标签的内容如下

<%@ page contentType="text/html; charset=GBK" %>

loginSuccess

您的密码没有成功修改

9、修改项目中的Spring IOC配置相关的*.xml文件

(1)在springapp-servlet.xml中定义修改信息的表单与控制器之间的关联

userLoginController

(2)在userManager.xml中增加下面的属性定义和注入

"https://www.sodocs.net/doc/e2705297.html,/dtd/spring-beans-2.0.dtd">

https://www.sodocs.net/doc/e2705297.html,erLoginForm

loginSuccess

loginFailure

userLogin/registerSuccess

userLogin/registerFailure

updateSuccess

updateFailure

10、将本示例的应用进行部署然后再进行测试

(1)出现下面的页面

(2)出现成功的提示

(3)同时在数据库表中应该出现下面的结果

相关主题