spring的事务管理实现.docx
《spring的事务管理实现.docx》由会员分享,可在线阅读,更多相关《spring的事务管理实现.docx(12页珍藏版)》请在冰豆网上搜索。
spring的事务管理实现
Spring提供的事务管理可以分为两类:
编程式的和声明式的。
编程式的,比较灵活,但是代码量大,存在重复的代码比较多;而声明式的比编程式的更灵活方便。
本文将讨论这两种事务管理的区别。
传统的JDBC事务管理
以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源是线程安全的,而连接不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。
一般的数据源由容器进行管理,包括连接池。
例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。
以往的我们使用JDBC在写代码时,事务管理可能会是这样:
Connectionconn=null;
try
{
conn=DBConnectionFactory.getConnection;
conn.setAutoCommit(false);
//dosomething
mit();//committranscation
}
catch(Exceptione)
{
conn.rollback();
//dosth
}
finally
{
try
{
conn.close();
}
catch(SQLExceptionse){//dosth.}
//closeResultSet,PreparedStatement,Connection
//notice:
MaybeocurrExceptionwhenuclosers,pstmt,conn
}
按照以往的思路来写代码,代码量比较长,而且容易疏忽,忘掉一些try/catch,引发一些异常无法catch,虽然有时候我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常。
Spring提供的编程式的事务处理
Spring提供了几个关于事务处理的类:
·TransactionDefinition//事务属性定义
·TranscationStatus//代表了当前的事务,可以提交,回滚。
·PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。
在TransactionDefinition接口中定义了五个不同的事务隔离级别:
1)ISOLATION_DEFAULT这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
2)ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3)ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。
另外一个事务不能读取该事务未提交的数据。
这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
4)ISOLATION_REPEATABLE_READ这种事务隔离级别可以防止脏读,不可重复读。
但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)
在TransactionDefinition接口中定义了七个事务传播行为:
1)#000000;">PROPAGATION_REQUIRED如果存在一个事务,则支持当前事务。
如果没有事务则开启一个新的事务;
2)PROPAGATION_SUPPORTS如果存在一个事务,支持当前事务。
如果没有事务,则非事务的执行;
3)PROPAGATION_MANDATORY如果已经存在一个事务,支持当前事务。
如果没有一个活动的事务,则抛出异;
4)PROPAGATION_REQUIRES_NEW总是开启一个新的事务。
如果一个事务已经存在,则将这个存在的事务挂起;
5)PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务;
6)PROPAGATION_NEVER总是非事务地执行,如果存在一个活动事务,则抛出异常;
7)PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED属性执行;
我们使用编程式的事务管理流程可能如下:
1声明数据源
2声明一个事务管理类,例如DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager等
3在我们的代码中加入事务处理代码:
TransactionDefinitiontd=newTransactionDefinition();
TransactionStatusts=transactionManager.getTransaction(td);
try
{
//dosth
transactionMmit(ts);
}
catch(Exceptione){transactionManager.rollback(ts);}
使用spring提供的事务模板TransactionTemplate
voidadd()
{
transactionTemplate.execute(newTransactionCallback(){
pulicObjectdoInTransaction(TransactionStatusts)
{//dosth}
}
}
TransactionTemplate也是为我们省去了部分事务提交、回滚代码;定义事务模板时,需注入事务管理对象.
Spring声明式事务处理
Spring声明式事务处理也主要使用了ioc,aop思想,提供了TransactionInterceptor拦截器和常用的代理类TransactionProxyFactoryBean,可以直接对组件进行事务代理。
使用TransactionInterceptor步骤
1.定义数据源,事务管理类
2.定义事务拦截器,suchas:
<beanid="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterceptor">
<propertyname="transactionManager"><refbean="transactionManager"/></property>
<propertyname="transactionAttributeSource">
<value>
com.test.UserManager.*r=PROPAGATION_REQUIRED
</value>
</property>
</bean>
3.为组件声明一个代理类:
ProxyFactoryBean
<beanid="userManager"class="org.springframework.aop.framework.ProxyFactoryBean">
<propertyname="proxyInterfaces"><value>com.test.UserManager</value></property>
<propertyname="interceptorNames">
<list>
<idreflocal="transactionInterceptor"/>
</list>
</property>
</bean>
使用TransactionProxyFactoryBean:
<beanid="userManager"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<propertyname="transactionManager"><refbean="transactionManager"/></property>
<propertyname="target"><reflocal="userManagerTarget"/></property>
<propertyname="transactionAttributes">
<props>
<propkey="insert*">PROPAGATION_REQUIRED</prop>
<propkey="update*">PROPAGATION_REQUIRED</prop>
<propkey="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
TransactionProxyFactoryBean只是为组件的事务代理,如果我们要给组件添加一些业务方面的验证等,可以使用TransactionTemplate加拦截器方式,为组件添加多个拦截器,springAOP中提供了三类Advice,即前增强,后增强,抛出异常时的增强,可以灵活使用。
步骤:
1. 配置AOP
--切面表达式匹配服务层的所有操作方法-->
config>
pointcutid="serviceMethods"expression="execution(*com.eway.test.TestService.*(..))"/>
advisoradvice-ref="txadvice"pointcut-ref="serviceMethods"/>
config>
切入范围:
execution(*com.eway.test.TestService.*(..))
advisor>指定事务通知
pointcut>通知由于特定的类或者方法
2. 配置事务通知
--通知事务-->
adviceid="txadvice"transaction-manager="TxManager">
attributes>
--需要用到的事务方法-->
methodname="insert*"/>
attributes>
advice>
3. 配置事务
--配置事务-->
4. 配置数据源:
省略
Spring事务和EJB事务相比
l Spring声明式事务在任何环境下都可以使用,只需要修改配置文件,它就可以和JDBC,JDO,Hibernate或和其他的事务机制一起使用,而EJB的CMT(声明式事务管理)是绑定在JTA上
l Sprin提供了回滚规则,而EJB没有
l Sprin允许通过AOP(切面)定制事务,可以随意添加任何事务通知,而EJB除了通过setRollbackOnly(),就没有办法影响容器管理事务了
l EJB事务可以跨越远程,而Sprin不提供
对Spring事务总结:
关于spring的事务配置由三个部分组成,分别是:
DataSource(数据源),TransactionManager(事务管理器),代理机制。
无论哪种事务配置方式,一般变化的是代理机制这部分。
对Spring的理解
Spring是一个轻量级的控制反转(IOC)和面向切面编程的框架
IOC:
将类的主动权移交给接口,通过容器实例化对象(容器通过反射机制创建对象)
AOP:
在修改源代码的情况下给系统加一个新的功能或者技术(例如:
一个登录程序,现在想记录登录日记,在不修改源代码的基础上,使用AOP写一个方法(称为通知)可以实现)
同时Spring提供支持事务,校验等等,使开发人员更容易编写更干净,更容易管理,更方便测试的代码。
Spring+Hibernate的实质:
就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理。
那么再没整合之前Hibernate是如何实现事务管理的呢?
通过ServletFilter实现数据库事务的管理,这样就避免了在数据库操作中每次都要进行数据库事务处理。
一.事务的4个特性:
原子性:
一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做,要么全部做。
一致性:
数据不会因为事务的执行而遭到破坏。
隔离性:
一个事务的执行,不受其他事务(进程)的干扰。
既并发执行的个事务之间互不干扰。
持久性:
一个事务一旦提交,它对数据库的改变将是永久的。
二.事务的实现方式:
实现方式共有两种:
编码方式;声明式事务管理方式。
基于AOP技术实现的声明式事务管理,实质就是:
在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
声明式事务管理又有两种方式:
基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。
三.创建事务的时机:
是否需要创建事务,是由事务传播行为控制的。
读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。
一种常见的事务管理配置:
事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式
--定义Hibernate的事务管理器HibernateTransactionManager-->
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
--依赖注入上面定义的sessionFactory-->
--定义Spring的事务拦截器TransactionInterceptor-->
--依赖注入上面定义的事务管理器transactionManager-->
--定义需要进行事务拦截的方法及所采用的事务控制类型-->
--以browse、list、load、get及is开头的所有方法采用只读型事务控制类型-->
PROPAGATION_REQUIRED,readOnly
PROPAGATION_REQUIRED,readOnly
PROPAGATION_REQUIRED,readOnly
PROPAGATION_REQUIRED,readOnly
PROPAGATION_REQUIRED,readOnly
--所有方法均进行事务控制,如果当前没有事务,则新建一个事务-->
PROPAGATION_REQUIRED
--定义BeanNameAutoProxyCreatorf进行Spring的事务处理-->
--针对指定的bean自动生成业务代理-->
adminService
columnsService
newsService
crawlService
memberLevelService
memberService
categoryService
merService
cartService
ordersService
trafficService
--这个属性为true时,表示被代理的是目标类本身而不是目标类的接口-->
true
--依赖注入上面定义的事务拦截器transactionInterceptor-->
transactionInterceptor
详细介绍Spring事务管理
、、
本文详细介绍Spring事务管理,包括Spring事务管理的两种方式——编程式和声明式。
、
在学习spring事务管理时,我忍不住要问,spring为什么进行事务管理,spring怎么进行的事务管理?
首先,为什么要进行事务,接下来说说spring是怎样进行事务管理的.
Spring事务策略
Spring事务策略,也就是spring事务管理的实现方式.它有一个统一的抽象是由实现下面这个接口完成的.org.springframework.transaction.PlatformTransactionManager
此接口的内容如下:
1.Public interface PlatformTransactionManager()...{
2.TransactionStatue getTransaction(TransactionDefinition definition) throws TransactionException;
3.Void commit(TransactionStatus status) throws TransactionException;
4.Void rollback(TransactionStatus status) throws TransactionException;
5.}
不管是声明式的还是编程式的事务管理都需要此抽象来完成.
解释一下这个接口,这样可以更好的理解spring的事务控制的原理.
getTransaction()根据类型为TransactionDefinition的参数返回一个TransactionStatus对象.返回的TransactionStatus对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务).如同J2EE事务上下文,一个TransactionStatus也是和执行的线程关联的.
同时,在框架中还存在TransactionDefinition接口,即上边的参数类型.此接口指定了事务隔离程度、事务传播、事务超时、只读状态。
另外,还有TransactionStatus接口。
这个接口为处理事务提供简单的控制事务执行和查询事务状态的方法。
两种Spring事务管理方式:
编程式、声明式。
Spring提供两种方式的编程式事务管理,分别是:
使用TransactionTemplate和直接使用PlatformTransactionManager。
1.TransactionTempale采用和其他Spring模板,如JdbcTempalte和HibernateTemplate一样的方法。
它使用回调方法,把应用程序从处理取得和释放资源中解脱出来。
如同其他模板,TransactionTemplate是线程安全的。
代码片段:
1.Object result = tt.execute(new TransactionCallback()...{
2.public Object doTransaction(TransactionStatus status)...{
3.updateOperation();
4.return resultOfUpdateOperation();
5.}
6.});
使用TransactionCallback()可以返回一个值。
如果使用TransactionCallbackWithoutResult则没有返回值。
2.也可以使用PlatformTransactionManager直接管理事务。
简单地通过一个bean引用给你的bean传递一个你使用的PlatformTransaction对象。
然后,使用TransactionDefinition和TransactionStatus对象就可以发起、回滚、提交事务。
如下片段:
1.Def