
2

3

4


5

6

7

接著再看一段代碼:( spring 中事務(wù)的一段學(xué)習(xí)代碼,這段代碼是把 spring 和 hibernate 結(jié)合在一起的,增加了理解上的難度,因?yàn)槲业某霭l(fā)點(diǎn)一開(kāi)始不要 hibernate ,就光用 jdbc 來(lái)進(jìn)行數(shù)據(jù)庫(kù)事務(wù),但是沒(méi)有其他好的代碼,就這樣吧)



2

3


4

5

6

7

8

9

10

11

12

13


14

15

16

17

18

19

在這個(gè)代碼的配置文件中,把 addLineItem 做為一個(gè)切入點(diǎn),進(jìn)行事務(wù),也就是說(shuō),在 addLineItem 的外面,再包上一層事務(wù)的外殼。
但是這個(gè)時(shí)候,問(wèn)題出來(lái)了,事務(wù)是針對(duì) Connection 的,而上面的兩個(gè)連續(xù)的 HibernateTemplate 執(zhí)行的 saveOrUpdate 中的 Connection 必須是一致才能用事務(wù), spring 怎么做到這一點(diǎn)的呢?(這個(gè)問(wèn)題也就是在找 spring 的事務(wù)例子前,我想的 spring 中用 jdbc 來(lái)進(jìn)行事務(wù),怎么樣讓 Connection 保持一致呢?但是沒(méi)有 jdbc 的例子,只有整合 hibernate 或者 ibatis 的例子,但是,我想,原理是一樣的吧。)
解決問(wèn)題的思路: HibernateTemplate 中的 Connection 必定一致。那么就從 HibernateTemplate 入手。
看 spring 的源代碼,既然是 Hibernate ,那么,就沒(méi)有 Connection 給你看,只有 Session ,由 Session 來(lái)管理 Connection ,那么用事務(wù)來(lái)控制的話(huà),這個(gè) Session 必定在所有該事務(wù)中是一致的。于是在 HibernateTemplate 中找到:



2

3



4

5

6

7

8

9



10

11

12

13

14

15



16

17

18

19

20

21

22

23

24

25

看來(lái)在 SessionFactoryUtils 里面,接著在 SessionFactoryUtils.getSession 中找:
這個(gè)方法太長(zhǎng)了,太復(fù)雜了,從簡(jiǎn),發(fā)現(xiàn)了非常關(guān)鍵的一點(diǎn):

2

3

假如 sessionHolder 不等于空,說(shuō)明,在事務(wù)中有這樣一個(gè)還沒(méi)有 commit 的 session ,那么就返回這個(gè) session ,假如等于空,新建一個(gè) session ,并且在事務(wù)里加入這個(gè) session 。這段代碼的意思大概是這樣,太繁雜了,只能猜,也肯定是如此。
再看 getHibernateTemplate() 方法來(lái)自繼承 HibernateDaoSupport ,看了電子書(shū)《 spring-reference 》的第九章“ Dao 支持”, Dao 的支持類(lèi)可以有好多,如: JdbcDaoSupport , HibernateDaoSupport , JdoDaoSupport 等等。
既然前面一開(kāi)始就是從 jdbc 的 spring 事務(wù)控制引起的,那么看到了同樣的 HibernateDaoSupport---JdbcDaoSupport ,那么 JdbcDaoSupport 也應(yīng)該有 getJdbcTemplate() 這個(gè)方法,并且返回 JdbcTemplate 這個(gè)類(lèi)。
果然如此。
于是剖析 JdbcTemplate 是不是和 HibernateTemplate 一樣。果然一樣。
注意到:

Connection 是從 DataSourceUtils.getConnection() 來(lái)的,繼續(xù)跟蹤 DataSourceUtils.getConnection() 。
找到:
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
和 Hibernate 中的一模一樣,因?yàn)闆](méi)有了 session 的封裝,條理在 jdbc 中更加清晰了。
至此, spring 的事務(wù)控制 已經(jīng)全部搞定。