首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Spring的事务管理难题剖析(1):DAO和事务管理的牵绊

2012-11-04 
Spring的事务管理难点剖析(1):DAO和事务管理的牵绊有些人很少使用Spring而不使用Spring事务管理器的应用,

Spring的事务管理难点剖析(1):DAO和事务管理的牵绊
   有些人很少使用Spring而不使用Spring事务管理器的应用,因此常常有人会问:是否用了Spring,就一定要用Spring事务管理器,否则就无法进行数据的持久化操作呢?事务管理器和DAO是什么关系呢?
  也许是DAO和事务管理如影随行的缘故吧,这个看似简单的问题实实在在地存在着,从初学者心中涌出,萦绕在老手的脑际。答案当然是否定的!我们都知道:事务管理是保证数据操作的事务性(即原子性、一致性、隔离性、持久性,即所谓的ACID),脱离了事务性,DAO照样可以顺利地进行数据的操作。

  JDBC访问数据库

  下面,我们来看一段使用Spring JDBC进行数据访问的代码:
 

package com.baobaotao.withouttx.jdbc;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Service;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.apache.commons.dbcp.BasicDataSource;@Service("userService")public class UserJdbcWithoutTransManagerService {    @Autowired    private JdbcTemplate jdbcTemplate;    public void addScore(String userName,int toAdd){        String sql = "UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?";        jdbcTemplate.update(sql,toAdd,userName);    }    public static void main(String[] args) {        ApplicationContext ctx = new              ClassPathXmlApplicationContext("com/baobaotao/withouttx/jdbc/jdbcWithoutTx.xml");                 UserJdbcWithoutTransManagerService service =                      (UserJdbcWithoutTransManagerService)ctx.getBean("userService");        JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate");        BasicDataSource basicDataSource = (BasicDataSource)jdbcTemplate.getDataSource();        //①检查数据源autoCommit的设置        System.out.println("autoCommit:"+ basicDataSource.getDefaultAutoCommit());        //②插入一条记录,初始分数为10        jdbcTemplate.execute("INSERT INTO t_user(user_name,password,score,last_logon_time)                               VALUES('tom','123456',10,"+System.currentTimeMillis()+")");        //③调用工作在无事务环境下的服务类方法,将分数添加20分        service.addScore("tom",20);         //④查看此时用户的分数        int score = jdbcTemplate.queryForInt(                  "SELECT score FROM t_user WHERE user_name ='tom'");        System.out.println("score:"+score);        jdbcTemplate.execute("DELETE FROM t_user WHERE user_name='tom'");    }}  

  其中,jdbcWithoutTx.xml的配置文件如下所示:
<?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:context="http://www.springframework.org/schema/context"       xmlns:p="http://www.springframework.org/schema/p"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">         <context:component-scan base-package="com.baobaotao.withouttx.jdbc"/>    <context:property-placeholder location="classpath:jdbc.properties"/>    <bean id="dataSource" p:driverClassName="${jdbc.driverClassName}"p:url="${jdbc.url}" p:username="${jdbc.username}"p:password="${jdbc.password}"/>    <bean id="jdbcTemplate" name="code">package com.baobaotao.withouttx.hiber;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;import org.springframework.stereotype.Service;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.orm.hibernate3.HibernateTemplate;import org.apache.commons.dbcp.BasicDataSource;import org.springframework.test.jdbc.SimpleJdbcTestUtils;import com.baobaotao.User;@Service("hiberService")public class UserHibernateWithoutTransManagerService {       @Autowired    private HibernateTemplate hibernateTemplate;    public void addScore(String userName,int toAdd){        User user = hibernateTemplate.get(User.class,userName);        user.setScore(user.getScore()+toAdd);        hibernateTemplate.update(user);    }    public static void main(String[] args) {        ApplicationContext ctx = new             ClassPathXmlApplicationContext("com/baobaotao/withouttx/hiber/hiberWithoutTx.xml");        UserHibernateWithoutTransManagerService service =              (UserHibernateWithoutTransManagerService)ctx.getBean("hiberService");        JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate");        BasicDataSource basicDataSource = (BasicDataSource)jdbcTemplate.getDataSource();        //①检查数据源autoCommit的设置        System.out.println("autoCommit:"+ basicDataSource.getDefaultAutoCommit());        //②插入一条记录,初始分数为10        jdbcTemplate.execute("INSERT INTO t_user(user_name,password,score,last_logon_time)                             VALUES('tom','123456',10,"+System.currentTimeMillis()+")");        //③调用工作在无事务环境下的服务类方法,将分数添加20分        service.addScore("tom",20);                //④查看此时用户的分数        int score = jdbcTemplate.queryForInt(                   "SELECT score FROM t_user WHERE user_name ='tom'");        System.out.println("score:"+score);        jdbcTemplate.execute("DELETE FROM t_user WHERE user_name='tom'");    }}

此时,采用hiberWithoutTx.xml的配置文件,其配置内容如下所示:
<?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:context="http://www.springframework.org/schema/context"       xmlns:p="http://www.springframework.org/schema/p"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <context:component-scan base-package="com.baobaotao.withouttx.hiber"/>    …    <bean id="sessionFactory"          name="code">package com.baobaotao;import javax.persistence.Entity;import javax.persistence.Table;import javax.persistence.Column;import javax.persistence.Id;import java.lang.reflect.Field;import java.io.Serializable;@Entity@Table(name="T_USER")public class User implements Serializable{    @Id    @Column(name = "USER_NAME")    private String userName;    private String password;    private int score;    @Column(name = "LAST_LOGON_TIME")    private long lastLogonTime = 0;    …}

   运行UserHibernateWithoutTransManagerService,程序正确执行,并得到类似于UserJdbcWithoutTransManagerService的执行结果。这说明Hibernate在Spring中,在没有事务管理器的情况下,依然可以正常地进行数据的访问。

  注:以上内容摘自《Spring 3.x企业应用开发实战》

Hibernate自身具备一个缺省的事务管理,只要用到了SessionFactory,也就意味着使用了这个事务控制。

有些人是这样配置的:

    <bean id="transactionManager" ref="sessionFactory"/>
    </bean>

其实,无需任何配置即可自动开启事务控制。

作者认同否?

--------------------------------------------------

此外,我建议使用以下配置:

        <property name="packagesToScan"> 
            <list> 
                <value>com.baobaotao</value> 
            </list> 
        </property>

这样也就无需一个个配置Entity类了。
最好把Entity集中放在一个目录中,这样就更好了。 3 楼 wzg1101 2012-06-11   文章写的很不错,不知楼主可不可以发一个多数据源的解决方案呢,网上看到的几种解决方案感觉都不是很好

热点排行