spring与hibernate中的事务.docx

上传人:b****7 文档编号:9491480 上传时间:2023-02-04 格式:DOCX 页数:25 大小:22.05KB
下载 相关 举报
spring与hibernate中的事务.docx_第1页
第1页 / 共25页
spring与hibernate中的事务.docx_第2页
第2页 / 共25页
spring与hibernate中的事务.docx_第3页
第3页 / 共25页
spring与hibernate中的事务.docx_第4页
第4页 / 共25页
spring与hibernate中的事务.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

spring与hibernate中的事务.docx

《spring与hibernate中的事务.docx》由会员分享,可在线阅读,更多相关《spring与hibernate中的事务.docx(25页珍藏版)》请在冰豆网上搜索。

spring与hibernate中的事务.docx

spring与hibernate中的事务

事务是信息化系统的最基本功能,基本的CRUD操作没有任何逻辑意义。

一次业务逻辑操作往往需要具有原子性:

典型的两个账户转账的情形,必然涉及两次数据库操作,这两次操作必须处于事务中,而不能只进行一半。

Hibernate建议所有的数据库访问都应放在事务内进行,即使只进行只读操作。

事务又应该尽可能短,因为长事务会导致长时间无法释放表内行级锁,从而降低系统并发的性能。

Spring同时支持编程式事务和声明式事务,尽量考虑使用声明式事务,因为声明式事务管理可分离业务逻辑和事务管理逻辑,具备良好的适应性。

编程式的事务管理

另外,编程式事务提供了TransactionTemplate模板类,该类可以大大减少事务操作的代码。

因此TransactionTemplate采用Callback避免让开发者重复书写其打开事务、提交事务及回滚事务等代码,同时TransactionTemplate无须书写大量的t可...catch块。

HibernateTemplate必须提供PlatformTransactionManager实例。

该实例既可以在代码中手动设置,也可以使用Spring的依赖注入。

总之,只要获取了PlatformTransactionManager引用,TransactionTemplate就可以完成事务操作。

使用TransactionTemplate不需要显式地开始事务,甚至不需要显式地提交事务。

这些步骤都由模板完成。

但出现异常时,应通过TransactionStatus的setRollbackOnly显式

回攘事务。

TransactionTemplate的execute方法接收一个TransactionCallback实例。

Callback也是Spring的经典设计,用于简化用户操作,TransactionCallback包含如下方法。

?

ObjectdolnTransaction(TransactionStatusstatus)。

该方法的方法体就是事务的执行体。

如果事务的执行体没有返回值,则可以使用TransactionCallbackWithoutResult1类的实例。

这是个抽象类,不能直接实例化,只能用于创建匿名内部类。

它也是TransactionCallback接口的子接口,该抽象类包含一个抽象方法:

?

voiddolnTransactionWithoutResult(TransactionStatusstatus)

该方法与dolnTransaction的效果非常相似,区别在于该方法没有返回值,即事务执行体无须返回值。

在下面的示例中,PlatformTransactionManager实例采用适用于Hibernate的事务管理器来实现类HibernateTransactionManager,该实现类是个局部事务管理器,容器中仅仅部署了该事务管理器bean,因此应在代码中于动为TransactionTemplate注入事务管理器bean。

下面是Hibernate局部事务管理的配置文件的源代码:

xmlversion="1.0"encoding="gb2312"?

>

--Spring配置文件的DTD定义一〉

DOCTYPEbeansPUBL工C"-//SPRING//DTDBEAN//EN"

''http:

//www.springfrarnework.org/dtd/sp工rng-beans.dtd">

<'…Spring配置文件的根元素是beans-->

--定义数据源,该bean的ID为dataSource-→

Dr工verManagerDataSource">

--指定数据库驱动-->

corn.rnysql.jdbc.Driver

value>

--指定连接数据库的URL-->

jdbc:

rnysql:

//wonder:

3306/j2ee

value>

一root为数据库的用户名一〉

root

--pass为数据库密码一〉

pass

一定义Hibernate的SessionFactory-->

LocalSessionFactoryBean">

一依赖注入数据源,注入上文定义的dataSource-->

一mappingResouces属性用来列出全部映射文件>

以下用来列出所有的PO映射文件一〉

lee/MyTest.hbm.xml

…定义Hibernate的SessionFactory的属性二〉

--指定Hibernate的连接方法-->

org.hibernate.dialect.

MySQLDialect

不同数据库连接,启动时选择create,update,create-drop-->

update

一配置Hibernate的事务管理器一〉

一使用HibernateTransactionManager类,该类是PlatformTransactionManager接口

针对采用Hibernate持久化连接的特定实现。

一〉

class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<'…HibernateTransactionManagerbean需要依赖注入一个

SessionFactorybean的引用-->

local="sessionFactory"I>

下面是采用TransactionTemplate和HibemateTemplate的事务操作代码:

publicclassTransactionTest

{

publicstaticvoidmain(String[]args)

{

/I因为并未在web应用中测试,故需要手动创建Spring的上下文

finalApplicationContextctx=

newFileSystemXrnlApplicationContext("bean.xml");

II获得Spring上下文的事务管理器

PlatformTransactionManagertransactionManager=

(PlatformTransactionManager)ctx.getBean("transactionManager");

finalSessionFactorysessionFactory=

(SessionFactory)ctx.getBean("sessionFactory");

/I以事务管理器实例为参数,创建TransactionTemplate对象

TransactionTemplatett=newTransactionTemplate(transactionManager);

II设置TransactionTemplate的事务传播属性

tt.setPropagationBehavior(TransactionDef工nition.PROPAGATION_REQUlRED);

II执行TransactionTemplate的execute方法,该方法需要TransactionCallback实例tt.execute(newTransactionCallbackW工thoutResult()

II采用TransactionCallbackWithoutResult匿名内部类的形式执行

protectedvoiddolnTransactionWithoutResult(TransactionStatusts)

try

{

以SessionFactory实例为参数创建HibernateTemplate

HibernateTemplatehibernateTemplate=

newHibernateTemplate(sessionFactory);

MyTestpl=丑ewMyTest("Jack");

II保存第一个实例

hibernateTemplate.save(pl);

II让下面的数据库操作抛出异常即可看出事务效果。

前面的操作也

II不会生效

MyTestp2=newMyTest("Jack");

II保存第二个实例,可将Person的name属性设为标识属性,并

II引起主键重复的异常,可看出前一条记录也不会加入数据库中

hibernateTemplate.save(p2);

}

catch(Exceptione)

{

ts.setRollbackOnly();

}).,

查看数据库的mytable表,该表中没有任何记录(如果没有采用事务,第一条记录应该可以进去。

而两次保存记录放在doInTransactionWithoutResult方法中执行),因为该方法的方法体具有事务性,该方法的数据库操作要么全部生效,要么全部失效。

由于第二条记录违反了数据库的主键约束,因此,记录全部失效。

声明式事务管理

通常建议采用声明式事务管理。

声明式事务管理的优势非常明显,代码中无须关注事务逻辑,由Spring声明式事务管理负责事务逻辑:

声明式事务管理无须与具体的事务逻辑糯合,可以方便地在不同事务逻辑之间切换。

声明式事务管理的配置方式通常有如下四种。

使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。

此方式最传统,但配置文件膝肿,难以阅读。

采用bean继承的事务代理配置方式比较简沽,但依然是增量式配置。

使用BeanNameAutoProxyCreator,根据beanname自动生成事务代理的方式,这是直接利用Spring的AOP框架配置事务代理的方式,需要对Spring的AOP框架有所理解,但这种方式避免了增量式配置,效果非常不错。

?

DefaultAdvisorAutoProxyCreator:

这也是直接利用Spring的AOP框架配置事务代理的方式,效果也非常不错,只是这种配置方式的可读性不如第三种方式。

1.利用TransactionProxyFactoryBean生成事务代理

采用这种方式的配置时,其配置文件的增加非常快,每个bean有需要两个bean配置一个目标,另外还需要使用TransactionProxyFactoryBean配置一个代理bean。

这是一种最原始的配置方式,下面是使用TransactionProxyFactoryBean的配置文件:

xmlversion="1.0"encoding="gb2312"?

>

<'一Spring配置文件的文件头,包含DTD等信息->

DOCTYPEbeansPUBL工C"-//SPRING//DTDBEAN//EN"

''http:

//www.springframework.org/dtd/spring-beans.dtd''>

一定义数据源>

DriverManagerDataSource">

一定义数据库驱动-->

com.mysql.jdbc.Driver

value>

定义数据库url-->

jdbc:

mysql:

//localhost:

3306/s工pnrg

value>

一定义数据库用户名>

root

<1--定义数据库密码一〉

32147

<'定义一个hibernate的SessionFactory-->

LocalSessionFactoryBean">

一定义SessionFactory必须注入DataSource-->

<1--以下用来列出所有的PO映射文件一〉

Person.hbm.xml

一此处用来定义hibernate的SessionFactory的属性:

不同数据库连接启动时选择create.update.create-drop-->

org.hibernate.dialect.

MySQLDialect

update

一定义事务管理器,适用于Hibernte的事务管理器一〉

class="org.springframework.口o口.hibernate3.HibernateTransactihoManager">

--HibernateTransactiohManagerbean需要依赖注入一个

SessionFactorybean的引用-->

property>

一定义DAOBean,作为事务代理的目标一〉

一为DAObean注入SessionFactory引用一〉

property>

一定义DAObean的事务代理>

TransactionProxyFactoryBean">

一为事务代理bean注入事务管理器一〉

/>

<'设置事务属性>

--所有以f工口d开头的方法,采用required的事务策略,并且只读…〉

PROPAGATION_REQU工RED,readOnly

…其他方法,采用required的事务策略->

PROPAGATION_REQUIRED

<'一为事务代理bean设置目标bean一〉

在上面的配置文件中,personDao需要配置两个部分:

一个是personDao的目标bean,该目标bean是实际DAObean,以实际的DAObean为目标,建立事务代理;另一个是组件,需要一个目标bean和一个事务代理来组成。

但这种配置方式还有一个缺点:

目标bean直接暴露在Spring容器中,可以直接引用,如果目标bean被误引用,将导致业务操作不具备事务性。

为了避免这种现象,可将目标bean配置成嵌套bean,~面是目标bean和事务代理的配置代码:

定义DAObean的事务代理一〉

TransactionProxyFactoryBean">

一为事务代理bean注入事务管理器>

>

一设置事务属性>

--所有以find开头的方法,采用required的事务策略,并且只读一〉

PROPAGAT工ON_REQUIRED,readOnly

其他方法,采用required的事务策略->

PROPAGATION_REQUIRED

一为事务代理bean设置目标bean-->

<'采用嵌套bean配置目标bean-->

一为DAObean注入SessionFactory引用一〉

2.利用继承简化配置

大部分情况下,每个事务代理的事务属性大同小异,事务代理的实现类都T是ransactionProxyFactoryBean,事务代理bean都必须注入事务管理器。

对于这种情况,Spring提供了bean与bean之间的继承,可以简化配置。

将大部分通用的配置,配置成事务模板,而实际的事务代理bean,则继承事务模板。

这种配置方式可以减少部分配置代码。

下面是采用继承的配置文件:

xmlversion="l.O"encoding="gb2312"?

>

--Spring配置文件的文件头,包含DTD等信息一〉

DOCTYPEbeansPUBLIC"-//SPR工NG//DTDBEAN//EN"

''http:

//www.springframework.org/dtd/spring-beans.dtd''>

一定义数据源二〉

DrJ.verManagerDataSource">

--定义数据库驱动一〉

com.mysql.jdbc.Driver

value>

--定义数据库url-->

jdbc:

mysql:

//localhost:

3306/spring

value>

-定义数据库用户名…〉

root

<1--定义数据库密码一〉

32147

--定义一个hibernate的SessionFactory-->

LocalSessionFactoryBean">

--定义Sess工onFactory必须注入DataSource-->

--以下用来列出所有的PO映射文件一〉

Person.hbm.xml

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 军事政治

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1