- 浏览: 1527284 次
- 性别:
- 来自: 厦门
博客专栏
-
Spring 3.x企业实...
浏览量:464210
文章分类
最新评论
-
JyeChou:
学习Spring必学的Java基础知识(1)----反射 -
hhzhaoheng:
...
《Spring4.x企业应用开发实战》光盘资料下载 -
renlongnian:
//assertReflectionEquals(user1, ...
单元测试系列之3:测试整合之王Unitils -
骑着蜗牛超F1:
huang_yong 写道我的经验是,只需定义三层:1.ent ...
Spring的事务管理难点剖析(2):应用分层的迷惑 -
wangyudong:
工具地址貌似更新了哦https://github.com/Wi ...
几种常用的REST webservice客户端测试工具
有些人很少使用Spring而不使用Spring事务管理器的应用,因此常常有人会问:是否用了Spring,就一定要用Spring事务管理器,否则就无法进行数据的持久化操作呢?事务管理器和DAO是什么关系呢?
也许是DAO和事务管理如影随行的缘故吧,这个看似简单的问题实实在在地存在着,从初学者心中涌出,萦绕在老手的脑际。答案当然是否定的!我们都知道:事务管理是保证数据操作的事务性(即原子性、一致性、隔离性、持久性,即所谓的ACID),脱离了事务性,DAO照样可以顺利地进行数据的操作。
JDBC访问数据库
下面,我们来看一段使用Spring JDBC进行数据访问的代码:
其中,jdbcWithoutTx.xml的配置文件如下所示:
运行UserJdbcWithoutTransManagerService,在控制台上打出如下的结果:
defaultAutoCommit:true
score:30
在jdbcWithoutTx.xml中,没有配置任何事务管理器,但是数据已经成功持久化到数据库中。在默认情况下,dataSource数据源的autoCommit被设置为true——这也意谓着所有通过JdbcTemplate执行的语句马上提交,没有事务。如果将dataSource的defaultAutoCommit设置为false,再次运行UserJdbcWithoutTransManagerService,将抛出错误,原因是新增及更改数据的操作都没有提交到数据库,所以代码清单10-1④处的语句因无法从数据库中查询到匹配的记录而引发异常。
对于强调读速度的应用,数据库本身可能就不支持事务:如使用MyISAM引擎的MySQL数据库。这时,无须在Spring应用中配置事务管理器,因为即使配置了,也是没有实际用处的。
Hibernate访问数据库
对于Hibernate来说,情况就有点复杂了。因为Hibernate的事务管理拥有其自身的意义,它和Hibernate一级缓存在密切的关系:当我们调用Session的save、update等方法时,Hibernate并不直接向数据库发送SQL语句,只在提交事务(commit)或flush一级缓存时才真正向数据库发送SQL。所以,即使底层数据库不支持事务,Hibernate的事务管理也是有一定好处的,不会对数据操作的效率造成负面影响。所以,如果是使用Hibernate数据访问技术,没有理由不配置HibernateTransactionManager事务管理器。
但是,不使用Hibernate事务管理器,在Spring中,Hibernate照样也可以工作,来看下面的例子:
此时,采用hiberWithoutTx.xml的配置文件,其配置内容如下所示:
com.baobaotao.User是使用了Hibernate注解的领域对象,代码如下所示:
运行UserHibernateWithoutTransManagerService,程序正确执行,并得到类似于UserJdbcWithoutTransManagerService的执行结果。这说明Hibernate在Spring中,在没有事务管理器的情况下,依然可以正常地进行数据的访问。
注:以上内容摘自《Spring 4.x企业应用开发实战》
也许是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" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/> </beans>
运行UserJdbcWithoutTransManagerService,在控制台上打出如下的结果:
引用
defaultAutoCommit:true
score:30
在jdbcWithoutTx.xml中,没有配置任何事务管理器,但是数据已经成功持久化到数据库中。在默认情况下,dataSource数据源的autoCommit被设置为true——这也意谓着所有通过JdbcTemplate执行的语句马上提交,没有事务。如果将dataSource的defaultAutoCommit设置为false,再次运行UserJdbcWithoutTransManagerService,将抛出错误,原因是新增及更改数据的操作都没有提交到数据库,所以代码清单10-1④处的语句因无法从数据库中查询到匹配的记录而引发异常。
对于强调读速度的应用,数据库本身可能就不支持事务:如使用MyISAM引擎的MySQL数据库。这时,无须在Spring应用中配置事务管理器,因为即使配置了,也是没有实际用处的。
Hibernate访问数据库
对于Hibernate来说,情况就有点复杂了。因为Hibernate的事务管理拥有其自身的意义,它和Hibernate一级缓存在密切的关系:当我们调用Session的save、update等方法时,Hibernate并不直接向数据库发送SQL语句,只在提交事务(commit)或flush一级缓存时才真正向数据库发送SQL。所以,即使底层数据库不支持事务,Hibernate的事务管理也是有一定好处的,不会对数据操作的效率造成负面影响。所以,如果是使用Hibernate数据访问技术,没有理由不配置HibernateTransactionManager事务管理器。
但是,不使用Hibernate事务管理器,在Spring中,Hibernate照样也可以工作,来看下面的例子:
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" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource"> <property name="annotatedClasses"> <list> <value>com.baobaotao.User</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFactory-ref="sessionFactory"/> </beans>
com.baobaotao.User是使用了Hibernate注解的领域对象,代码如下所示:
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 4.x企业应用开发实战》
评论
5 楼
vae_in_zdsoft
2014-04-29
关于mysql使用spring事务管理无效有解决方案么,是说用mysql的数据库 无法使用spring事务管理?
4 楼
xs.cctv
2013-07-31
不错!支持
3 楼
wzg1101
2012-06-11
文章写的很不错,不知楼主可不可以发一个多数据源的解决方案呢,网上看到的几种解决方案感觉都不是很好
2 楼
huang_yong
2012-04-14
写得很好!
Hibernate自身具备一个缺省的事务管理,只要用到了SessionFactory,也就意味着使用了这个事务控制。
有些人是这样配置的:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
其实,无需任何配置即可自动开启事务控制。
作者认同否?
--------------------------------------------------
此外,我建议使用以下配置:
<property name="packagesToScan">
<list>
<value>com.baobaotao</value>
</list>
</property>
这样也就无需一个个配置Entity类了。
最好把Entity集中放在一个目录中,这样就更好了。
Hibernate自身具备一个缺省的事务管理,只要用到了SessionFactory,也就意味着使用了这个事务控制。
有些人是这样配置的:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
其实,无需任何配置即可自动开启事务控制。
作者认同否?
--------------------------------------------------
此外,我建议使用以下配置:
<property name="packagesToScan">
<list>
<value>com.baobaotao</value>
</list>
</property>
这样也就无需一个个配置Entity类了。
最好把Entity集中放在一个目录中,这样就更好了。
1 楼
jfzlnyf
2012-03-14
hibernate不配事物也会给你开一个默认事物的。。。。
发表评论
-
一个常见的Spring IOC疑难症状
2013-07-25 14:14 5061Case 请看下面的IOC实例: 1)Aa ... -
mybatis3.1分页自动添加总数
2013-07-08 21:11 22837问题 1.mybatis默认分页是内存分页的,谁用谁崩溃啊! ... -
Rop开发手册(1):最简单的服务开放平台框架
2012-08-08 11:35 8617Rop概述 Rop是Rapid Open Pl ... -
学习Spring必学的Java基础知识(9)----HTTP请求报文
2012-06-09 16:02 13942引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
学习Spring必学的Java基础知识(8)----国际化信息
2012-05-26 11:19 28471引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(7)----事务基础知识
2012-05-26 10:57 5089引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
学习Spring必学的Java基础知识(6)----ThreadLocal
2012-05-19 10:09 12138引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(5)----注解
2012-05-19 09:56 5776引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
学习Spring必学的Java基础知识(4)----XML基础知识
2012-05-12 15:33 8560引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(3)----PropertyEditor
2012-05-12 15:13 16846引述要学习Spring框架的 ... -
明明白白AOP(傻瓜也会心领神会!)
2012-05-05 11:04 10584引子: AOP(面向方面编 ... -
学习Spring必学的Java基础知识(2)----动态代理
2012-05-02 13:03 9713引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(1)----反射
2012-04-25 13:57 89790引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
透透彻彻IoC(你没有理由不懂!)
2012-04-18 11:01 94214引述:IoC(控制反转:I ... -
单元测试系列之5:使用unitils测试Service层
2012-04-14 10:48 18446引述:Spring 的测试框架为我们提供一个强大的测试环境,解 ... -
如何用Spring读取JAR中的文件
2012-04-13 17:22 18399使用如下方式读取JAR中的文件出错 类路径下 ... -
单元测试系列之4:使用Unitils测试DAO层
2012-04-12 16:32 19683Spring 的测试框架为我们提供一个强大的测试环境,解 ... -
单元测试系列之3:测试整合之王Unitils
2012-04-09 14:11 15660引述:程序测试对保障应用程序正确性而言,其重要性怎么样强调都不 ... -
单元测试系列之2:模拟利器Mockito
2012-03-30 11:38 15312引述:程序测试对 ... -
单元测试系列之1:开发测试的那些事儿
2012-03-28 12:52 10014引述:程序测试对保障应用程序正确性而言,其重要性怎 ...
相关推荐
首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 1. **编程式事务管理**:通过使用`PlatformTransactionManager`接口及其实现类(如`JdbcTemplate`或`HibernateTemplate`),开发者...
在Spring框架中,事务管理是实现业务逻辑时不可或缺的一部分,它确保了数据的一致性和完整性。本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理...
Spring事务管理主要包括两种类型:编程式事务管理和声明式事务管理。 - **编程式事务管理**:通过编写代码来控制事务的开始、提交或回滚等操作。这种方式灵活度高,但会使得代码变得冗余且难以维护。 - **声明式...
实验 "Spring 声明事务" 是 Java 高级编程中的一个重要环节,旨在让学生掌握 Spring 框架中声明式事务管理的配置和使用。在实际应用中,事务管理是确保数据一致性、完整性和可靠性的关键组件。Spring 提供了声明式...
Spring支持两种类型的事务管理:编程式事务管理和声明式事务管理。其中声明式事务管理因其易于使用和维护而被广泛采用。 ##### 1.1 Spring声明式事务介绍 Spring的声明式事务管理是通过配置文件或注解的方式来实现...
7. **案例分析**:"SPRING事务管理案例分析.docx"很可能包含了具体的项目实例,详细讲解了如何在Spring项目中配置和使用事务管理,以及如何解决实践中遇到的问题。而"studyspring"可能是源代码目录,包含了实现这些...
这些传播行为可以帮助我们处理嵌套事务和其他复杂的事务场景。 另外,事务的隔离级别也是需要考虑的重要因素。Spring支持四种隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE,它们...
在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本教程将深入探讨如何在Spring中实现自定义事务管理器、编程式事务处理以及声明式事务`@Transactional`的使用。 首先,让我们了解事务...
本文将全面分析Spring中的编程式事务管理和声明式事务管理,旨在帮助开发者深入理解这两种事务管理方式,并在实际项目中合理选择。 **编程式事务管理** 编程式事务管理是通过代码直接控制事务的开始、提交、回滚等...
Spring 框架的事务管理是其核心特性之一,它为开发者提供了强大的支持,确保了在多线程和并发环境中数据的一致性和完整性。本教程将深入探讨 Spring 的编程式事务管理和声明式事务管理,帮助你理解这两种方式的差异...
本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...
在Java企业级应用开发中,Spring框架以其强大的功能和灵活性被广泛应用,特别是在事务管理方面。Spring提供了全面的事务管理解决方案,使得开发者可以方便地控制事务的边界,保证数据的一致性和完整性。本篇将深入...
Spring 3.0 提供了两种事务管理配置方法:基于 XML 的事务管理和基于 @Transactional 的事务管理,这两种方法都是为了实现事务管理的目标,分别具有不同的配置方式和优缺点。 基于 XML 的事务管理 这种方法不需要...
标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...
案例中的"springStudy04_transaction"可能包含了一个使用Spring进行事务管理的简单应用程序,其中可能包括了数据库连接配置、数据访问对象(DAO)的实现以及事务控制的代码。你可以通过阅读源代码来了解如何在实际...
在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一过程。 首先,我们来看Spring事务的流程。当一个事务开始时,通常会经历以下步骤: 1. *...
【Spring框架的事务管理应用分析】 Spring框架是一个在2003年推出的开源项目,它的核心设计理念源于Rod Johnson的《Expert One-on-One J2EE Design and Development》一书中的实用主义J2EE思想。Spring框架主要包括...
在 Spring 2.5 中,事务管理可以分为两种:本地事务和分布式事务。本地事务是指在同一个进程中对数据源的访问,分布式事务是指跨多个进程或系统对数据源的访问。 本地事务配置文件: 在 Spring 2.5 中,本地事务的...
文件名如"spring-jdbc-tran1"、"spring-jdbc-tran2"和"spring-jdbc-tran3"暗示了实验可能涉及Spring与JDBC的事务交互。在Spring中,DataSourceTransactionManager是用于JDBC事务管理的默认实现。使用它,你可以控制...