Spring的事务,经典配(一)

2014-11-24 02:22:07 · 作者: · 浏览: 0

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


1.spring 分享

先看一段代码:

Java代码
connection conn = conn.getconnection(); conn.setautocommit(false); …….. ……... conn.rollback(); conn.commit();


数据库的事务是针对 connection 的。

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


Java代码
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 中找到:


Java代码
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 中找:

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

Java代码
sessionholder sessionholder = (sessionholder) transactionsynchronizationmanager.getresource(sessionfactory);


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

再看 gethibernatetemplate() 方法来自继承 hibernatedaosupport ,看了电子书《 spring- reference 》的第九章“ dao 支持”, dao 的支持类可以有好多,如: jdbcdaosupport , hibernatedaosupport , jdodaosupport 等等。

既然前面一开始就是从 jdbc 的 spring 事务控制引起的,那么看到了同样的 hibernatedaosupport---jdbcdaosupport ,那么 jdbcdaosupport 也应该有 getjdbctemplate() 这个方法,并且返回 jdbctemplate 这个类。

果然如此。

于是剖析 jdbctemplate 是不是和 hibernatetemplate 一样。果然一样。

注意到:

Java代码
connection con = datasourceutils.getconnection(getdatasource());


connection 是从 datasourceutils.getconnection() 来的,继续跟踪 datasourceutils.getconnection() 。

找到:

Java代码
connectionholder conholder = (connectionholder) transactionsynchronizationmanager.getresource(datasource);


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

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

2.spring 事务管理的配置

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

Java代码
mf/org/user/user.hbm.xml