知识大全 Spring的事务

Posted

篇首语:学者有自立之志,当拔出流俗,不可泛泛与世浮沉。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Spring的事务相关的知识,希望对你有一定的参考价值。

Spring的事务  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  今天对 spring 的 AOP 事务有了一个新的认识 所以赶紧把今天的学习记下来 希望在今后的学习中能够起到一些作用 也能对今天的认识做一次总结

   spring 分享

  先看一段代码

  Connection conn = Conn getConnection();

  conn setAutoCommit(false);

  ……

  ……

  conn rollback();

  mit();

  数据库的事务是针对 Connection 的

  接着再看一段代码 ( spring 中事务的一段学习代码 这段代码是把 spring 和 hibernate 结合在一起的 增加了理解上的难度 因为我的出发点一开始不要 hibernate 就光用 jdbc 来进行数据库事务 但是没有其他好的代码 就这样吧)

  public Long addLineItem(Long orderId LineItem lineItem)

  log( OrderListDAOHibernate addLineItem : Start );

  OrderList orderList = (OrderList) getHibernateTemplate() load(OrderList class orderId);

  lineItem setOrderList(orderList);

  getHibernateTemplate() saveOrUpdate(lineItem);

  getHibernateTemplate() saveOrUpdate(orderList);

  log( OrderListDAOHibernate addLineItem : Ending );

  return lineItem getId();

  

  在这个代码的配置文件中 把 addLineItem 做为一个切入点 进行事务 也就是说 在 addLineItem 的外面 再包上一层事务的外壳

  但是这个时候 问题出来了 事务是针对 Connection 的 而上面的两个连续的 HibernateTemplate 执行的 saveOrUpdate 中的 Connection 必须是一致才能用事务 spring 怎么做到这一点的呢?(这个问题也就是在找 spring 的事务例子前 我想的 spring 中用 jdbc 来进行事务 怎么样让 Connection 保持一致呢?但是没有 jdbc 的例子 只有整合 hibernate 或者 ibatis 的例子 但是 我想 原理是一样的吧 )

  解决问题的思路 HibernateTemplate 中的 Connection 必定一致 那么就从 HibernateTemplate 入手

  看 spring 的源代码 既然是 Hibernate 那么 就没有 Connection 给你看 只有 Session 由 Session 来管理 Connection 那么用事务来控制的话 这个 Session 必定在所有该事务中是一致的 于是在 HibernateTemplate 中找到

  protected Session getSession()

  if (isAlwaysUseNewSession())

  return SessionFactoryUtils getNewSession(getSessionFactory() getEntityInterceptor());

  

  else if (!isAllowCreate())

  return SessionFactoryUtils getSession(getSessionFactory() false);

  

  else

  return SessionFactoryUtils getSession(

  getSessionFactory() getEntityInterceptor() getJdbcExceptionTranslator());

  

  

  看来在 SessionFactoryUtils 里面 接着在 SessionFactoryUtils getSession 中找

  这个方法太长了 太复杂了 从简 发现了非常关键的一点

  SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager getResource(sessionFactory);

  假如 sessionHolder 不等于空 说明 在事务中有这样一个还没有 mit 的 session 那么就返回这个 session 假如等于空 新建一个 session 并且在事务里加入这个 session 这段代码的意思大概是这样 太繁杂了 只能猜 也肯定是如此

  再看 getHibernateTemplate() 方法来自继承 HibernateDaoSupport 看了电子书《 spring reference 》的第九章 Dao 支持 Dao 的支持类可以有好多 如 JdbcDaoSupport HibernateDaoSupport JdoDaoSupport 等等

  既然前面一开始就是从 jdbc 的 spring 事务控制引起的 那么看到了同样的 HibernateDaoSupport JdbcDaoSupport 那么 JdbcDaoSupport 也应该有 getJdbcTemplate() 这个方法 并且返回 JdbcTemplate 这个类

  果然如此

  于是剖析 JdbcTemplate 是不是和 HibernateTemplate 一样 果然一样

  注意到

  Connection con = DataSourceUtils getConnection(getDataSource());

  Connection 是从 DataSourceUtils getConnection() 来的 继续跟踪 DataSourceUtils getConnection()

  找到

  ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager getResource(dataSource);

  和 Hibernate 中的一模一样 因为没有了 session 的封装 条理在 jdbc 中更加清晰了

  至此 spring 的事务控制 已经全部搞定

   Spring 事务管理的配置

  看了上面同事学习 spring 的笔记后自己也觉得有新的理解 从什么地方说起呢?就从 spring 的事务配置说起吧 那么我们看看 contextConfig xml 吧

  <bean id= sessionFactory class= springframework orm hibernate LocalSessionFactoryBean >

  <property name= dataSource >

  <ref bean= dataSource />

  </property>

  <property name= mappingResources >

  <list>

  <value>mf//user/User hbm xml</value>

  </list>

  </property>

  </bean>

  <bean id= transactionManager class= springframework orm hibernate HibernateTransactionManager >

  <property name= sessionFactory >

  <ref local= sessionFactory />

  </property>

  </bean>

  <bean id= txProxyTemplate abstract= true class= springframework transaction interceptor TransactionProxyFactoryBean >

  <property name= transactionManager >

  <ref bean= transactionManager />

  </property>

  <property name= transactionAttributes >

  <props>

  <prop key= save* >PROPAGATION_REQUIRED Exception</prop>

  <prop key= remove* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= update* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= incress* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= * >PROPAGATION_REQUIRED readOnly</prop>

  </props>

  </property>

  </bean>

  <bean id= userManager parent= txProxyTemplate >

  <property name= target ref= userManagerTarget />

  </bean>

  <bean id= userManagerTarget

  class= hb user service impl UserManagerImpl >

  <property name= userDAO ref= userDAO />

  </bean>

  <bean id= userDAO class= hb user dao hibernate UserDAOHibernate >

  <property name= sessionFactory ref= sessionFactory />

  </bean>

  以上就是一个完整的 spring 配置 是不是很熟悉呢 这里是用的 Appfuse 的框架 呵呵 有那么点味道吧

  首先我们看看

  <bean id= transactionManager class= springframework orm hibernate HibernateTransactionManager >

  <property name= sessionFactory >

  <ref local= sessionFactory />

  </property>

  </bean>

  这一个 bean 让 spring 为我们注入了什么呢?事务 对!我们把 hibernate 的事务注入到了 spring 的 IOC 容器之中了 然后我们再看看

  <bean id= txProxyTemplate abstract= true class= springframework transaction interceptor TransactionProxyFactoryBean >

  <property name= transactionManager >

  <ref bean= transactionManager />

  </property>

  <property name= transactionAttributes >

  <props>

  <prop key= save* >PROPAGATION_REQUIRED Exception</prop>

  <prop key= remove* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= update* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= incress* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= * >PROPAGATION_REQUIRED readOnly</prop>

  </props>

  </property>

  </bean>

  这个 bean 又是让 spring 为我们注入了了什么呢?事务代理 对了!我们把事务的代理交给一个 txProxyTemplate 的去做了 这样的好处我待会再说 现在我们看看下面的一些配置信息

  <prop key= save* >PROPAGATION_REQUIRED Exception</prop>

  <prop key= remove* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= update* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= incress* >PROPAGATION_REQUIRED Exception </prop>

  <prop key= * >PROPAGATION_REQUIRED readOnly</prop>

  这里就是事务处理时如果遇到异常信息 或者其他的原因时我们要求 spring 把当前的事务回滚了 这样才能不至于在数据库中产生垃圾啊 我们规定所有的 save remove update incress 这样的方法开头的在出现一些问题后把事务给回滚了 看看我们写的 PROPAGATION_REQUIRED Exception

  有人就会说 PROPAGATION_REQUIRED 就可以回滚事务啊 为什么加上 Exception 呢?其实我以前也时这样想的 但这是不完全正确的 当然我们在处理一个事务时只要有一个 PROPAGATION_REQUIRED 就可以了 但是当我们的业务逻辑中要求我们在一个事务代理中开启两个事务 这两个事务表面上没有联系 但是实际中又有很多联系的 比如我们上传附件和提交文档 这样两个操作我们可以分开 因为他们不是往一个表里插入数据 我们又不希望这两个操作写在一个 service 里 这样我们要是有一个业务只要上传附件呢?那样我们是不是又要再写一个方法啊!所以在开启两个事务时如果有一个抛出异常了 我们就要把上一个提交的事务回滚了 这样做我们就要用的 Exception 了 这样就完全满足我们的要求了 我也试过如果我写的是 PROPAGATION_REQUIRED SQLException 时 这样我们只会在出现 SQLException 时事务回顾 出现其他的异常事务就不回滚了 好在 spring 可以让我们写如异常的基类就可以做到捕获任何异常 这样我们就写 Exception 好了 特殊情况在特殊处理吧 通用情况下我们还是这样的

  我们再看看

  <bean id= userManager parent= txProxyTemplate >

  <property name= target ref= userManagerTarget />

  </bean>

  <bean id= userManagerTarget

  class= hb user service impl UserManagerImpl >

  <property name= userDAO ref= userDAO />

  </bean>

  <bean id= userDAO class= hb user dao hibernate UserDAOHibernate >

  <property name= sessionFactory ref= sessionFactory />

  </bean>

  当然我们也可以写成

  <bean id= userManager parent= txProxyTemplate >

  <property name= target >

  <bean class= hb user service impl UserManagerImpl >

  <property name= userDAO >

  <ref bean= userDao />

  </property>

  </bean>

  </property>

  </bean>

  <bean id= userDAO class= hb user dao hibernate UserDAOHibernate >

  <property name= sessionFactory ref= sessionFactory />

  </bean>

  这下我们解除以前的疑惑 parent= txProxyTemplate 知道我们为什么在上面先写了 txProxyTemplate 的 bean 了吧 这样我们就没有必要再写一编了 是不是很方便? spring 的这些技巧还不只这些呢 这样我们就可以轻松利用以上这三个注入的类去做我们的逻辑了

  Spring 就是要我们注入实现类 然后使用接口操作 这样耦合性就不是那么强了 这也体现了 Spring 的工厂模式 而 AOP 的 manager 又象我们熟知的代理模式吧 !

   注意要点

cha138/Article/program/Java/ky/201311/28161

相关参考

知识大全 Spring声明式事务管理源码解读之事务开始

Spring声明式事务管理源码解读之事务开始  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在s

知识大全 Spring 事务管理

Spring事务管理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  数据库事务是由一系列的动作组

知识大全 spring事务配置

  <!构建HibernateTransactionManager用于获得session管理事务>  <beanid=transactionManagerclass=springfr

知识大全 Spring+Ibatis+事务处理

Spring+Ibatis+事务处理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  applic

知识大全 Spring事务深入浅出

Spring事务深入浅出  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  &n

知识大全 浅析Spring提供的事务管理方法

浅析Spring提供的事务管理方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Spring提

知识大全 Spring中事务的传播属性详解

Spring中事务的传播属性详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我们用Sprin

知识大全 Spring中的事务传播属性详解

Spring中的事务传播属性详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在使用Sprin

知识大全 Spring中的四种声明式事务的配置

Spring中的四种声明式事务的配置  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Spring

知识大全 在Spring中配置Hibernate的事务

在Spring中配置Hibernate的事务  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文