4. 在Spring配置文件中配置JOTM
代码清单 1 applicationContext-jta.xml
…
首先,我们在①处通过Spring所提供的JotmFactoryBean创建一个本地JOTM实例,该实例同时实现了 javax.transaction.UserTransaction和javax.transaction.TransactionManager接口,它可以和ObjectWeb的XAPool一起工作。
JTA事务管理器通过userTransaction属性引用本地JOTM实例,Spring的JtaTransactionManager会自动探测到传入的javax.transaction.UserTransaction引用也实现了javax.transaction.TransactionManager,所以我们无需再配置JtaTransactionManager的transactionManager属性,如②所示。
在Spring中配置JOTM的另一个关键问题是配置XAPool,支持JTA事务的数据源必须封装成XAPool。首先,我们通过org.enhydra.jdbc.standard.StandardXADataSource 配置一个XA数据源,它指向topicdb数据库,如③-1所示。而后,通过org.enhydra.jdbc.pool.StandardXAPoolDataSource将其封装成一个XAPool,如③所示。按照相同的方式,配置指向postdb数据库的XAPool,如④所示。
接下来的配置就顺理成章了,分别使用Spring JDBC的模板类配置DAO类,然后再配置引用DAO类的业务类。关于Spring JDBC的详细内容,参见第10章的内容。
这里,我们使用@Transaction注解对业务类BbtForumImpl进行事务声明,所以通过<tx:annotation-driven/>对此进行驱动,BbtForumImpl的代码如下所示:
代码清单 2 BbtForumImpl
BbtForumImpl将Dao类组织起来,PostDao和TopicDao分别访问不同数据库中表,通过Spring注解驱动事务切面的增强后,它们将工作于同一个JTA事务中。
代码清单 1 applicationContext-jta.xml
…
<
bean id
=
"
jotm
"
class
=
"
org.springframework.transaction.jta.JotmFactoryBean
"
/>
①JOTM本地实例 ②JTA事务管理器
<
bean id
=
"
txManager
"
class
=
"
org.springframework.transaction.jta.JtaTransactionManager
"
>
<
property name
=
"
userTransaction
"
ref
=
"
jotm
"
/>
②
-
1
:指定userTransaction属性
</
bean
>
③XAPool配置,内部包含了一个XA数据源,对应topicdb数据库
<
bean id
=
"
topicDS
"
class
=
"
org.enhydra.jdbc.pool.StandardXAPoolDataSource
"
destroy
-
method
=
"
shutdown
"
>
<
property name
=
"
dataSource
"
>
③
-
1
:内部XA数据源
<
bean
class
=
"
org.enhydra.jdbc.standard.StandardXADataSource
"
destroy
-
method
=
"
shutdown
"
>
<
property name
=
"
transactionManager
"
ref
=
"
jotm
"
/>
<
property name
=
"
driverName
"
value
=
"
com.MySQL.jdbc.Driver
"
/>
<
property name
=
"
url
"
value
=
"
jdbc:MySQL://localhost:3309/topicdb
"
/>
</
bean
>
</
property
>
<
property name
=
"
user
"
value
=
"
root
"
/>
<
property name
=
"
password
"
value
=
"
1234
"
/>
</
bean
>
④按照③相似的方式配置另一个XAPool,对应postdb数据库,
<
bean id
=
"
postDS
"
class
=
"
org.enhydra.jdbc.pool.StandardXAPoolDataSource
"
destroy
-
method
=
"
shutdown
"
>
<
property name
=
"
dataSource
"
>
<
bean
class
=
"
org.enhydra.jdbc.standard.StandardXADataSource
"
destroy
-
method
=
"
shutdown
"
>
<
property name
=
"
transactionManager
"
ref
=
"
jotm
"
/>
<
property name
=
"
driverName
"
value
=
"
com.mysql.jdbc.Driver
"
/>
<
property name
=
"
url
"
value
=
"
jdbc:mysql://localhost:3309/postdb
"
/>
</
bean
>
</
property
>
<
property name
=
"
user
"
value
=
"
root
"
/>
<
property name
=
"
password
"
value
=
"
1234
"
/>
</
bean
>
⑤配置访问topicDB数据源的Spring JDBC模板
<
bean id
=
"
topicTemplate
"
class
=
"
org.springframework.jdbc.core.JdbcTemplate
"
>
<
property name
=
"
dataSource
"
ref
=
"
topicDS
"
/>
</
bean
>
⑥配置访问postDB数据源的Spring JDBC模板
<
bean id
=
"
postTemplate
"
class
=
"
org.springframework.jdbc.core.JdbcTemplate
"
>
<
property name
=
"
dataSource
"
ref
=
"
postDS
"
/>
</
bean
>
⑦基于topicTemplate数据源的topicDao
<
bean id
=
"
topicDao
"
class
=
"
com.baobaotao.dao.jdbc.TopicJdbcDao
"
>
<
property name
=
"
jdbcTemplate
"
ref
=
"
topicTemplate
"
/>
</
bean
>
⑧基于postTemplate数据源的postDao
<
bean id
=
"
postDao
"
class
=
"
com.baobaotao.dao.jdbc.PostJdbcDao
"
>
<
property name
=
"
jdbcTemplate
"
ref
=
"
postTemplate
"
/>
</
bean
>
⑨进行跨数据库JTA事务的业务类
<
bean id
=
"
bbtForum
"
class
=
"
com.baobaotao.service.impl.BbtForumImpl
"
>
<
property name
=
"
topicDao
"
ref
=
"
topicDao
"
/>
<
property name
=
"
postDao
"
ref
=
"
postDao
"
/>
</
bean
>
⑩对BbtForumImpl业务类中的@Transaction注解进行驱动
<
tx:annotation
-
driven transaction
-
manager
=
"
txManager
"
/>
JTA事务管理器通过userTransaction属性引用本地JOTM实例,Spring的JtaTransactionManager会自动探测到传入的javax.transaction.UserTransaction引用也实现了javax.transaction.TransactionManager,所以我们无需再配置JtaTransactionManager的transactionManager属性,如②所示。
在Spring中配置JOTM的另一个关键问题是配置XAPool,支持JTA事务的数据源必须封装成XAPool。首先,我们通过org.enhydra.jdbc.standard.StandardXADataSource 配置一个XA数据源,它指向topicdb数据库,如③-1所示。而后,通过org.enhydra.jdbc.pool.StandardXAPoolDataSource将其封装成一个XAPool,如③所示。按照相同的方式,配置指向postdb数据库的XAPool,如④所示。
接下来的配置就顺理成章了,分别使用Spring JDBC的模板类配置DAO类,然后再配置引用DAO类的业务类。关于Spring JDBC的详细内容,参见第10章的内容。
这里,我们使用@Transaction注解对业务类BbtForumImpl进行事务声明,所以通过<tx:annotation-driven/>对此进行驱动,BbtForumImpl的代码如下所示:
代码清单 2 BbtForumImpl
package com.baobaotao.service.impl; import org.springframework.transaction.annotation.Transactional; import com.baobaotao.dao.PostDao; import com.baobaotao.dao.TopicDao; import com.baobaotao.domain.Forum; import com.baobaotao.domain.Topic; import com.baobaotao.service.BbtForum; @Transactional ①事务注解,以便Spring动态织入事务管理功能
public
class
BbtForumImpl implements BbtForum
{ private TopicDao topicDao; private PostDao postDao; public voidaddTopic(Topic topic) throws Exception { ②将方法将被施加JTA事务的增强 topicDao.addTopic(topic); postDao.addPost(topic.getPost()); }}