Thinking in sky

--老贺的BLOG

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 0 文章 :: 35 评论 :: 0 Trackbacks
先看一段代码:
1Connection conn = Conn.getConnection();
2    conn.setAutoCommit(false);
3    ……..
4    ……
5    conn.rollback();
6    conn.commit(); 
7
数据库的事务是针对 Connection 的。

   
接着再看一段代码:( spring 中事务的一段学习代码,这段代码是把 spring hibernate 结合在一起的,增加了理解上的难度,因为我的出发点一开始不要 hibernate ,就光用 jdbc 来进行数据库事务,但是没有其他好的代码,就这样吧)
 1public Long addLineItem(Long orderId, LineItem lineItem)
 2
 3       log("OrderListDAOHibernate.addLineItem : Start"); 
 4
 5       OrderList orderList = (OrderList) getHibernateTemplate().load(OrderList.class, orderId); 
 6
 7       lineItem.setOrderList(orderList); 
 8
 9       getHibernateTemplate().saveOrUpdate(lineItem); 
10
11       getHibernateTemplate().saveOrUpdate(orderList); 
12
13       log("OrderListDAOHibernate.addLineItem : Ending"); 
14
15       return lineItem.getId(); 
16
17    }

18
19

在这个代码的配置文件中,把 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 中找到:

 1protected Session getSession() 
 2
 3       if (isAlwaysUseNewSession()) 
 4
 5return SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()); 
 6
 7       }
 
 8
 9       else if (!isAllowCreate()) 
10
11return SessionFactoryUtils.getSession(getSessionFactory(), false); 
12
13       }
 
14
15       else 
16
17return SessionFactoryUtils.getSession( 
18
19                  getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()); 
20
21       }
 
22
23    }
 
24
25

看来在 SessionFactoryUtils 里面,接着在 SessionFactoryUtils.getSession 中找:

 

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

1SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); 
2
3

假如 sessionHolder 不等于空,说明,在事务中有这样一个还没有 commit 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 的事务控制 已经全部搞定。

posted on 2007-05-11 17:42 老贺 阅读(396) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问