spring2.0中的事务控制

 spring的事务控制应该说是所有用spring的项目中必不可少的东西。在我所经历过的所有用spring的项目中,IOC和事务控制是必用的。其它的一些东西,根据项目不同会有所选择。为什么要用spring的这两个呢?使用IOC可以让我们的代码进行完全的松耦合。而事务控制,可以让我们基本上在写代码的时候短暂的忘记事务的存在。专心于业务层的实现。下面给出一个spring 事务控制的例子。首页是Action层的代码:

public  String createUser()  throws  Exception  {
        user 
= new User();
        user.setUsername(
"Gavin");
        user.setPassword(
"123");
        user.setUserDetail(
new UserDetail());    
        
        
if (logger.isDebugEnabled()) {
            logger.debug(
"创建一个新的用户. " + user.toString());
        }

        
        
try {
            userService.saveUser(user);

        }
 catch (Exception e) {
            
if (logger.isDebugEnabled()) {
                logger.debug(
"用户操作出错. " + e);
            }

        }

        
        
return Action.SUCCESS;
    }

Action层只是简单的去调用service层,为了使例子简单,我去掉了一些不必要的东西。只剩下核心的一些。下面给出service层的代码(所有接口用处不大,不给出来)。

package  com.websidesoft.service.impl;

import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;

import  com.websidesoft.dao.iface.FriendDAO;
import  com.websidesoft.dao.iface.UserDAO;
import  com.websidesoft.entities.User;
import  com.websidesoft.exception.WSSException;
import  com.websidesoft.service.iface.UserService;

public   class  UserServiceManager  implements  UserService  {
    
private static final Log logger = LogFactory.getLog(UserServiceManager.class);
    
    
private FriendDAO friendDao;
    
private UserDAO userDao;
    

    
public void deleteUser(int userId) throws WSSException {
    }


    
public User getUser(int userId) throws WSSException {
        
return null;
    }


    
public void saveUser(User user) throws WSSException {
        userDao.saveUser(user);
        
        
try {
            friendDao.saveFriend(user);
        }
 catch (Exception e) {
            
if (logger.isDebugEnabled()) {
                logger.debug(
"保存friend出错. " + e);
            }
            
        }

        
//        throw new RuntimeException("出错.............");
    }

    
    
public void updateUser(User user) throws WSSException {
        
    }


    
public FriendDAO getFriendDao() {
        
return friendDao;
    }


    
public void setFriendDao(FriendDAO friendDao) {
        
this.friendDao = friendDao;
    }


    
public UserDAO getUserDao() {
        
return userDao;
    }


    
public void setUserDao(UserDAO userDao) {
        
this.userDao = userDao;
    }


}

service是重点,给出了所有service层的代码。先给出所有的代码,之后再来详细说明。下面是DAO层代码:

 

package  com.websidesoft.dao.impl;

import  java.util.HashMap;
import  java.util.Map;

import  org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import  org.springframework.jdbc.core.support.JdbcDaoSupport;

import  com.websidesoft.dao.iface.UserDAO;
import  com.websidesoft.entities.User;
import  com.websidesoft.exception.DataAccessException;

public   class  UserDAOImpl  extends  JdbcDaoSupport  implements  UserDAO  {

    
public void deleteUser(int userId) throws DataAccessException {
    }


    
public User getUser(int userId) throws DataAccessException {
        
return null;
    }


    
public void saveUser(User user) throws DataAccessException {
        String sql 
= "insert into wss_users(username, password) values (:username, :password)";
        
        NamedParameterJdbcTemplate pstmt 
= new NamedParameterJdbcTemplate(this.getJdbcTemplate().getDataSource());
        Map nameParameters 
= new HashMap();
        nameParameters.put(
"username", user.getUsername());
        nameParameters.put(
"password", user.getPassword());
    
        pstmt.update(sql, nameParameters);
    }


    
public void updateUser(User user) throws DataAccessException {
    }

}


package  com.websidesoft.dao.impl;

import  org.springframework.jdbc.core.support.JdbcDaoSupport;

import  com.websidesoft.dao.iface.FriendDAO;
import  com.websidesoft.exception.DataAccessException;

public   class  FriendDAOImpl  extends  JdbcDaoSupport  implements  FriendDAO  {

    
public void saveFriend(Object o) throws DataAccessException {
        
throw new NullPointerException("不能传入空的参数.");
    }

}

为了简单和测试,我在FriendDAO中直接抛出异常。下面给出xml配置文件,只是核心的,还有一些bean的ioc就不写出来了。

<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
         xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:aop
="http://www.springframework.org/schema/aop"
         xmlns:tx
="http://www.springframework.org/schema/tx"
          xmlns:jee
="http://www.springframework.org/schema/jee"
         xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"
>

    
       
< bean  id ="dataSource"  class ="org.springframework.jndi.JndiObjectFactoryBean" >
        
< property  name ="jndiName"  value ="java:comp/env/jdbc/wss" />
    
</ bean >
    
    
< bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        
< property  name ="dataSource"  ref ="dataSource" />
    
</ bean >
    
    
< tx:advice  id ="txAdvice"  transaction-manager ="transactionManager" >
        
< tx:attributes >
            
< tx:method  name ="save*" />
            
< tx:method  name ="get*" />
        
</ tx:attributes >
    
</ tx:advice >
    
    
< aop:config >
        
< aop:pointcut  id ="userServicePointcut"  expression ="execution(* com.websidesoft.service.iface.UserService.*(..))" />
        
< aop:advisor  advice-ref ="txAdvice"  pointcut-ref ="userServicePointcut" />
        
< aop:aspect  id ="userAspect"  ref ="userLog" >
              
< aop:before  pointcut ="execution(* com.websidesoft.service.iface.UserService.*(..)) and args(user)"  method ="saveUser" />
        
</ aop:aspect >
    
</ aop:config >
    
    
    
<!--  DAO层  -->
    
< bean  id ="userDao"  class ="com.websidesoft.dao.impl.UserDAOImpl" >
        
< property  name ="dataSource"  ref ="dataSource" />
    
</ bean >
    
    
< bean  id ="friendDao"  class ="com.websidesoft.dao.impl.FriendDAOImpl" >
        
< property  name ="dataSource"  ref ="dataSource" />
    
</ bean >
</ beans >

上面给出了这个例子的所有代码。下面首先说明一下事务控制的部份。核心的事务控制部份如下:

< bean  id ="dataSource"  class ="org.springframework.jndi.JndiObjectFactoryBean" >
        
< property  name ="jndiName"  value ="java:comp/env/jdbc/wss" />
    
</ bean >
    
    
< bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        
< property  name ="dataSource"  ref ="dataSource" />
    
</ bean >
    
    
< tx:advice  id ="txAdvice"  transaction-manager ="transactionManager" >
        
< tx:attributes >
            
< tx:method  name ="save*" />
            
< tx:method  name ="get*" />
        
</ tx:attributes >
    
</ tx:advice >

上面的配置实现了以容器的方式配置数据源。对数据源进行事务管理。看一下service层的代码:

public   void  saveUser(User user)  throws  WSSException  {
        userDao.saveUser(user);
        
        
try {
            friendDao.saveFriend(user);
        }
 catch (Exception e) {
            
if (logger.isDebugEnabled()) {
                logger.debug(
"保存friend出错. " + e);
            }
            
        }

        
//        throw new RuntimeException("出错.............");
    }

在上面的代码中,如果出现错误,将抛出WSSException异常。这个异常是实现了Exception的全局异常。spring在对事务控制时,只对运行时异常和未检测异常才会进行事务的rollback,也就是说当抛出检测异常将不会被rollback。看上面的例子,我对friendDao.saveFriend(user)进行了try catch动作。因为在friendDao中,我直接抛出抛常。也就是说如果friendDao出错,将不能影响到用户的正常注册。上面的异常不会导致事务回滚。上面的代码运行进,将会用户正常的注册。在下面,我把一行代码注释了,throw new RuntimeException("出错.............");这一代码有什么作用呢?这一句最重要的作用就是,如果打开,那么所有的事务将进行rollback操作。也就是说保存用户将会出错。不会保存成功。

上面只是简单的举了个例子来说明spring2.0中事务控制。当然,还可以控制指定哪些异常将会导致回滚动作。只需要在事务控制的xml中加上rollback-for="异常全名"即可。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值