gpt4 book ai didi

spring声明式事务解析

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 31 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章spring声明式事务解析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、spring声明式事务 。

1.1 spring的事务管理器 。

spring没有直接管理事务,而是将管理事务的责任委托给JTA或相应的持久性机制所提供的某个特定平台的事务实现。spring容器负责事物的操作,spring容器充当切面,事务的方法称为增强处理,生成的代理对象的方法就是目标方法+增强也就是crud+事务程序员只用做crud的操作,也就是目标方法和声明哪些方法应该在事务中运行.

Spring提供了许多内置事务管理器实现:

DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理; JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理; JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理; HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本; JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器; OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持; WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持; WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。 Spring不仅提供这些事务管理器,还提供对如JMS事务管理的管理器等,Spring提供一致的事务抽象如图所示 。

spring声明式事务解析

spring与hibernate 。

spring声明式事务解析

说明:

spring在调用具体的事务管理器之前做了一些准备工作,提前设置事务的读写策略,而这些事务策略是公共的东西,是写在spring的配置文件中的,这些内容的处理需要放在抽象类中去做 。

2、spring与hibernate整合中的事务处理 。

1.2 以xml形式 引入properties配置文件 。

?
1
2
3
< property name = "locations" >
   < value >classpath:jdbc.properties</ value >
</ property >

配置dbcp数据源 。

?
1
2
3
4
5
6
<bean id= "dataSource" destroy-method= "close" class = "org.apache.commons.dbcp.BasicDataSource" >
     <property name= "driverClassName" value= "${jdbc.driverClassName}" />
     <property name= "url" value= "${jdbc.url}" />
     <property name= "username" value= "${jdbc.username}" />
     <property name= "password" value= "${jdbc.password}" />
  </bean>

引入sessionfactory,使用hibernate外部配置文件 。

?
1
2
3
4
5
<bean id= "sessionFactory2" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
     <property name= "configLocation" >
       <value>classpath:hibernate.cfg.xml</value>
     </property>
</bean>

注入dao和service层 。

?
1
2
3
4
5
6
7
8
9
10
11
<bean id= "personDao" class = "cn.qjc.hibernate.dao.impl.PersonDaoImpl" >
   <property name= "sessionFactory" >
     <ref bean= "sessionFactory2" />
   </property>
</bean>
 
<bean id= "personService" class = "cn.qjc.hibernate.service.impl.PersonServiceImpl" >
   <property name= "personDao" >
     <ref bean= "personDao" />
   </property>
</bean>

 配置hibernate事务管理器 。

?
1
2
3
4
5
<bean id= "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" >
   <property name= "sessionFactory" >
     <ref bean= "sessionFactory2" />
   </property>
  </bean>

配置声明式事务 。

作用:

  1、告诉spring容器事务管理器 。

  2、告诉spring容器什么样的方法使用什么样的事务 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<tx:advice transaction-manager= "transactionManager" id= "tx" >
   <tx:attributes>
     <!-- 
       name 目标方法的范围
       islation 隔离级别
       propagation 传播属性      
       read-only
         true 只读事务
         false 读写事务
      -->
     <tx:method name= "save*" isolation= "DEFAULT" propagation= "REQUIRED" read-only= "false" />
   </tx:attributes>
  </tx:advice>

配置切入点 。

?
1
2
3
4
5
<aop:config>
   <aop:pointcut expression= "execution(* cn.qjc.hibernate.service.impl.*.*(..))" id= "perform" />
     <span style= "white-space:pre" > </span><!-- 将切入点应用到增强方法 -->
   <aop:advisor advice-ref= "tx" pointcut-ref= "perform" />
  </aop:config>

dao实现类 。

?
1
2
3
4
5
6
7
8
9
10
* 实现方法一:继承HibernateDaoSupport
  * @author qjc
  */
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao{
 
   @Override
   public void savePerson(Person person) {
     this .getHibernateTemplate().save(person);
   }
}

测试 。

... 。

注意:

1、如果一个DAO类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了.

2、如果一个DAO类没有继承HibernateDaoSupport,需要有一个SessionFactory的属性,并且在配置文件中进行注入.

?
1
2
3
<bean id= "hibernateTemplate" class = "org.springframework.orm.hibernate3.HibernateTemplate" >
   <property name= "sessionFactory" ref= "sessionFactory2" ></property>
</bean>

1.2 以注解形式 。

1、在配置文件中应用spring的自动扫描机制 。

<context:component-scan base-package="cn.qjc"/> 。

2、在配置文件中引入注解解析器 。

<tx:annotation-driven transaction-manager="transactionManager"/> 。

3、在service层通过@Transaction进行注解  。

注意:如果在类级别上被注解为只读事务,但是这个类中的方法中@Transaction注解的事务设置将优先于类级别注解的事务设置.

1.3 spring事务的传播属性 。

  required: 业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新事务(默认) 。

  not-supported:spring容器不开启事务,如果方法在一个事务中被调用,该事务会被挂起,该方法结束后,事务恢复 。

  requiresnew:不管是否存在事务,业务方法总会创建一个新事务.

  mandatorky: 业务方法只能在一个已经存在的事务中执行,如果业务方法在没有事务下调用,容器抛出例外.

此外还有supports、never、nested等属性,但是通常使用默认 。

propagation="required" 此配置可以解决事务嵌套问题,何为事务嵌套?

比如:

spring声明式事务解析

在工作流框架和操作service层的某个方法中都存在事务,service层也有自己的事务,当service执行的时候,就会出现事务嵌套,即方法本身有事务,方法中的方法还有事务,这就是事务嵌套。而spring通过事务传播属性propagation="required"解决了这一问题.

 1.4 OpenInSessionView 。

在s2sh整合以后,spring管理事务,由于使用的是spring的声明式事务处理方式,所以在调用this.getHibernateTemplate()这个方法执行完之后,session立即关闭,如果当前执行的方法有事务,当事务环境的方法被调用完毕后session关闭。所以当值在页面输出时会产生异常.

处理方式为:OpenSessionInview模式(web.xml中配置) 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<filter>
   <filter-name>hibernateFilter</filter-name>
   <filter- class >org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter- class >
   
   <!-- singleSession默认为 true ,若设置为 false 则等于没有OpenSessionInView -->
   <init-param>
     <param-name>singleSession</param-name>
     <param-value> true </param-value>
   </init-param>
  </filter>
 
  <filter-mapping>
   <filter-name>hibernateFilter</filter-name>
  <url-pattern>/PersonService</url-pattern>  
  </filter-mapping>

从上面代码可以看出,当提交一个请求时,OpenSessionInView中已经把session开启了,在response以后才要关闭session,也就意味着有了openSessionInView必须在struts2的过滤器之前。(放struts2过滤器位置上面)  。

但是开启OpenSessionInView也有缺点:因为session关闭被延后了,而hibernate的一级缓存在session中,所以会导致大量的缓存中的数据被长时间停留在内存中.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.

最后此篇关于spring声明式事务解析的文章就讲到这里了,如果你想了解更多关于spring声明式事务解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com