日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

在Spring中使用JTA事务管理

發(fā)布時間:2025/3/19 javascript 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Spring中使用JTA事务管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在Spring中使用JTA事務管理

Spring 通過AOP技術可以讓我們在脫離EJB的情況下享受聲明式事務的豐盛大餐,脫離Java EE應用服務器使用聲明式事務的道路已經(jīng)暢通無阻。但是很大部分人都還認為脫離Java EE應用服務器就無法使用JTA事務,這是一個誤解。其實,通過配合使用ObjectWeb的JOTM開源項目,不需要Java EE應用服務器,Spring也可以提供JTA事務。

正因為AOP讓Spring擁有了脫離EJB容器的聲明式事務能力,而JOTM讓我們在脫離Java EE應用服務器下?lián)碛蠮TA事務能力。所以,人們將AOP和JOTM稱為Java軟件開發(fā)的兩個圣杯。

本文將講解Spring在不同環(huán)境下提供JTA事務的配置過程,這包括:Spring中直接集成JOTM提供JTA事務管理、將JOTM集成到Tomcat中,Spring通過引用Tomcat JNDI數(shù)據(jù)源提供JTA事務管理、引用其他功能完善JavaEE應用服務器所提供的JTA事務管理。

通過集成JOTM,直接在Spring中使用JTA事務

JOTM(Java Open Transaction Manager)是ObjectWeb的一個開源JTA實現(xiàn),它本身也是開源應用程序服務器JOnAS(Java Open Application Server)的一部分,為其提供JTA分布式事務的功能。

Spring 2.0附帶的依賴類庫中雖然包含jotm類庫,但是并不完整,你可以到http://jotm.objectweb.org下載完全版的JOTM。

Spring為JOTM提供了一個org.springframework.transaction.jta.JotmFactoryBean支持類,通過該支持類可以方便地創(chuàng)建JOTM本地實例。

下面,我們通過配置,使上節(jié)中BbtForumImpl#addTopic()方法工作在JTA事務的環(huán)境下。addTopic()內(nèi)部使用兩個DAO類(TopicDao和PostDao)分別訪問不同數(shù)據(jù)庫中的表。通過下面的步驟說明了使addTopic()方法擁有JTA事務的整個過程:

?

1. 將JOTM以下類庫添加到類路徑中:

jotm.jar

xapool.jar

jotm_jrmp_stubs.jar

jta-spec1_0_1.jar

connector-1_5.jar

2. 編寫JOTM配置文件,放到類路徑下

carol.properties

#JNDI調(diào)用協(xié)議

carol.protocols=jrmp

#不使用CAROL JNDI封裝器

carol.start.jndi=false

#不啟動命名服務器

carol.start.ns=false

3. 在MySQL上建立兩個數(shù)據(jù)庫

在MySQL數(shù)據(jù)庫中運行SQL腳本,建立topicdb和postdb兩個數(shù)據(jù)庫,在topicdb數(shù)據(jù)庫中創(chuàng)建t_topic表,在postdb數(shù)據(jù)庫中創(chuàng)建t_post表。我們希望在這兩個數(shù)據(jù)庫上進行JTA事務。SQL腳本如下所示:


DROP DATABASE IF EXISTS topicdb;
CREATE DATABASE topicdb DEFAULT CHARACTER SET utf8;
USE topicdb;
drop table if exists t_topic;
create table t_topic
(
topic_id int(11) not null auto_increment,
forum_id int(11) not null default 0,
topic_title varchar(100) not null default '',
user_id int(11) not null default 0,
topic_time datetime default NULL,
topic_views int(11) default 1,
topic_replies int(11) default 0,
primary key (topic_id)
);
create index IDX_TOPIC_USER_ID on t_topic
(
user_id
);

?


DROP DATABASE IF EXISTS postdb;
CREATE DATABASE postdb DEFAULT CHARACTER SET utf8;
USE postdb;
create table t_post
(
post_id int(11) not null auto_increment,
topic_id int(11) not null default 0,
forum_id int(11) not null default 0,
user_id int(11) not null default 0,
post_text text,
post_attach blob,
post_time datetime default NULL,
primary key (post_id)
);
create index IDX_POST_TOPIC_ID on t_post
(
topic_id
);

?

4. 在Spring配置文件中配置JOTM

代碼清單 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配置,內(nèi)部包含了一個XA數(shù)據(jù)源,對應topicdb數(shù)據(jù)庫

<bean id="topicDS" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"

destroy-method="shutdown">

<property name="dataSource">

③-1:內(nèi)部XA數(shù)據(jù)源

<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數(shù)據(jù)庫,

?

<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數(shù)據(jù)源的Spring JDBC模板

<bean id="topicTemplate"

class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource" ref="topicDS" />

</bean>

⑥配置訪問postDB數(shù)據(jù)源的Spring JDBC模板

<bean id="postTemplate"

class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource" ref="postDS" />

</bean>

⑦基于topicTemplate數(shù)據(jù)源的topicDao

<bean id="topicDao" class="com.baobaotao.dao.jdbc.TopicJdbcDao">

?

<property name="jdbcTemplate" ref="topicTemplate" />

</bean>

⑧基于postTemplate數(shù)據(jù)源的postDao

<bean id="postDao" class="com.baobaotao.dao.jdbc.PostJdbcDao">

<property name="jdbcTemplate" ref="postTemplate" />

</bean>

⑨進行跨數(shù)據(jù)庫JTA事務的業(yè)務類

<bean id="bbtForum" class="com.baobaotao.service.impl.BbtForumImpl">

<property name="topicDao" ref="topicDao" />

<property name="postDao" ref="postDao" />

</bean>

⑩對BbtForumImpl業(yè)務類中的@Transaction注解進行驅(qū)動

<tx:annotation-driven transaction-manager="txManager" />

首 先,我們在①處通過Spring所提供的JotmFactoryBean創(chuàng)建一個本地JOTM實例,該實例同時實現(xiàn)了  javax.transaction.UserTransaction和javax.transaction.TransactionManager接 口,它可以和ObjectWeb的XAPool一起工作。

JTA事務管理器通過userTransaction屬性引用本地JOTM實例,Spring的JtaTransactionManager會自動探測 到傳入的javax.transaction.UserTransaction引用也實現(xiàn)了 javax.transaction.TransactionManager,所以我們無需再配置JtaTransactionManager的 transactionManager屬性,如②所示。

在Spring中配置JOTM的另一個關鍵問題是配置XAPool,支持JTA事務的數(shù)據(jù)源必須封裝成XAPool。首先,我們通過 org.enhydra.jdbc.standard.StandardXADataSource 配置一個XA數(shù)據(jù)源,它指向topicdb數(shù)據(jù)庫,如③-1所示。而后,通過 org.enhydra.jdbc.pool.StandardXAPoolDataSource將其封裝成一個XAPool,如③所示。按照相同的方 式,配置指向postdb數(shù)據(jù)庫的XAPool,如④所示。

?

接下來的配置就順理成章了,分別使用Spring JDBC的模板類配置DAO類,然后再配置引用DAO類的業(yè)務類。關于Spring JDBC的詳細內(nèi)容,參見第10章的內(nèi)容。

這里,我們使用@Transaction注解對業(yè)務類BbtForumImpl進行事務聲明,所以通過<tx:annotation-driven/>對此進行驅(qū)動,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動態(tài)織入事務管理功能
public class BbtForumImpl implements BbtForum ...{
private TopicDao topicDao;
private PostDao postDao;
public void addTopic(Topic topic) throws Exception ...{ ②將方法將被施加JTA事務的增強
topicDao.addTopic(topic);
postDao.addPost(topic.getPost());
}
}

BbtForumImpl將Dao類組織起來,PostDao和TopicDao分別訪問不同數(shù)據(jù)庫中表,通過Spring注解驅(qū)動事務切面的增強后,它們將工作于同一個JTA事務中。

5. 在Spring中運行測試

代碼清單 3 TestBbtForumJta

package com.baobaotao.service;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

public class TestBbtForumJta extends AbstractDependencyInjectionSpringContextTests...{
private BbtForum bbtForum;
private final Logger logger = Logger.getLogger(getClass());
public void setBbtForum(BbtForum bbtForum) ...{
this.bbtForum = bbtForum;
}
protected String[] getConfigLocations() ...{
return new String[]...{"classpath:applicationContext-jta.xml"};
}
public void testAddPost() throws Exception...{
logger.info("begin........");
Topic topic = new Topic();
topic.setTopicTitle("Title -pfb");
Post post = new Post();
post.setPostText("post content -pfb");
topic.setPost(post);
bbtForum.addTopic(topic); ①使用了JTA事務的業(yè)務方法
logger.info("end........");
}
}

?

通過Spring測試類AbstractDependencyInjectionSpringContextTests的支持,很容易編寫一個測試類, 對啟用了JTA事務的BbtForum#addTopic()方法進行測試。建議你將Log4J設置為DEBUG,這樣就可以通過豐富的輸出日志觀測到 JTA事務的執(zhí)行情況。運行這個測試類后,你將可以看到JTA事務被正確實施。

Spring引用Tomcat的 JTA事務

Tomcat是Servlet容器,但它提供了JNDI的實現(xiàn),因此用戶可以象在Java EE應用程序服務器中一樣,在Tomcat中使用JNDI查找JDBC數(shù)據(jù)源。在事務處理方面,Tomcat本身并不支持JTA,但是可以通過集成JOTM達到目的。

如果你的應用最終部署到一個功能齊備的Java EE應用服務器上,也許你更希望使用Java EE應用服務器的JTA功能,這樣可以利用應用服務器本身許多優(yōu)化措施。下面,我們讓Tomcat通過JNDI開放JOTM的JTA的數(shù)據(jù)源,進而在Spring容器引用這個JNDI數(shù)據(jù)源,并在此基礎上提供JTA事務。我們所使用的環(huán)境是:Tomcat 5.5+JOTM 2.3。

1. 添加所需的JAR文件

將JOTM以下類包添加到<Tomcat安裝目錄>/common/lib目錄中:

jotm.jar

jotm_jrmp_stubs.jar

jotm_iiop_stubs.jar

ow_carol.jar

jta-spec1_0_1.jar

jts1_0.jar

objectweb-datasource.jar

xapool.jar

howl.jar

connector-1_5.jar

同時,還需要添加相應數(shù)據(jù)庫的JDBC驅(qū)動類包,例如MySQL的mysql.jar。

2. 配置JOTM

新建一個carol.properties配置文件,放置到<Tomcat安裝目錄>/common/classes目錄下,配置文件內(nèi)容如下:

#JNDI調(diào)用協(xié)議

carol.protocols=jrmp

# 本地RMI調(diào)用

carol.jvm.rmi.local.call=true

?

# 不使用CAROL的JNDI封裝器

carol.start.jndi=false

# 不啟用命名服務器

carol.start.ns=false

# 命名工廠類

carol.jndi.java.naming.factory.url.pkgs=org.apache.naming

將carol.start.jndi設置為false,讓JOTM不使用CAROL JNDI wrapper,從而可以避免類裝載錯誤的發(fā)生。

3. 配置Tomcat環(huán)境,配置JNDI的數(shù)據(jù)源

在<Tomcat安裝目錄>/conf/context.xml文件中添加以下內(nèi)容:

<Resource name="jdbc/topicDS" auth="Container" type="javax.sql.DataSource" ①-1:JNDI數(shù)據(jù)源

factory="org.objectweb.jndi.DataSourceFactory"

username="root" password="1234"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3309/topicdb"

maxActive="30" maxIdle="30"/>

<Resource name="jdbc/postDS" auth="Container" type="javax.sql.DataSource" ①-2:JNDI數(shù)據(jù)源

factory="org.objectweb.jndi.DataSourceFactory"

username="root" password="1234"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3309/postdb"

maxActive="30" maxIdle="30"/>

②JOTM JTA事務管理

<Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>

在Tomcat中配置兩個JNDI數(shù)據(jù)源,它們分別指向topicdb和postdb數(shù)據(jù)庫,如①處所示。最后配置JOTM的JTA事務管理器,該事務管理器自動對兩個JNDI中的數(shù)據(jù)源應用JTA事務。

?

4. Spring中相應的配置

讓應用服務器提供JNDI數(shù)據(jù)源管理和JTA事務后,Spring肩上的擔子減輕了許多,Spring要做的只是簡單地引用JNDI的數(shù)據(jù)源,并啟用JtaTransactionManager就可以了。

代碼清單 4 applicationContext-jta-tomcat.xml:使用應用服務器的JTA支持

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">

①使用Tomcat JNDI的數(shù)據(jù)源

<jee:jndi-lookup id="topicDS" jndi-name="java:comp/env/jdbc/topicDS" />
<jee:jndi-lookup id="postDS" jndi-name="java:comp/env/jdbc/postDS" />
<bean id="topicTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="topicDS" />
</bean>
<bean id="postTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="postDS" />
</bean>
<bean id="topicDao" class="com.baobaotao.dao.jdbc.TopicJdbcDao">
<property name="jdbcTemplate" ref="topicTemplate" />
</bean>
<bean id="postDao" class="com.baobaotao.dao.jdbc.PostJdbcDao">
<property name="jdbcTemplate" ref="postTemplate" />
</bean>
<bean id="bbtForum" class="com.baobaotao.service.impl.BbtForumImpl">
<property name="topicDao" ref="topicDao" />
<property name="postDao" ref="postDao" />
</bean>

②只需要指定一個JTA事務管理器就可以了,Spring會自動使用Tomcat中的JTA事務功能

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
<tx:annotation-driven transaction-manager="txManager" />
</beans>

?

在①處,我們通過Spring jee命名空間提供的<jee:jndi-lookup>標簽獲取應用服務器中的JNDI資源,并將它們聲明為一個Bean以供持久化模板類引用。

和直接在Spring中使用JOTM不一樣,這時,我們僅需要簡單地配置一個JtaTransactionManager就可以了,該事務管理器將自動將JTA事務委托給應用程序器。

Spring引用Java EE應用服務器 JTA事務功能和 Tomcat+JOTM提供JTA事務功能的配置步驟基本相似,相信大家可以對照這個實例完成相應的配置。另外,這里的實例采用了Spring JDBC作為持久層實現(xiàn)技術,你完全可以通過少量的調(diào)整將其應用到JPA、Hibernate、iBatis等持久化實現(xiàn)技術中。

在特定應用服務器使用JTA

一般來說,Spring的事務抽象與應用服務器是無關的。不過,如果你如果希望事務管理器使用特定的UserTransaction 和 TransactionManager 對象(可以被自動探測),以獲取更多的增強事務語義。這時,針對不同的Java EE應用服務器,Spring的事務管理器可以采取不同的配置。

? BEA WebLogic

在一個使 用WebLogic 7.0、8.1或更高版本的環(huán)境中,你一般會優(yōu)先選用特定于WebLogic的 WebLogicJtaTransactionManager 類來取代基礎的 JtaTransactionManager 類,因為在WebLogic環(huán)境中,該類提供了對Spring事務定義的完全支持,超過了標準的JTA語義。你可以使用以下的配置達到目的:

<bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>

它的特性包括:支持事務名,支持為每個事務定義隔離級別,以及在任何環(huán)境下正確地恢復事務的能力。

? IBM WebSphere

在WebSphere 5.1、5.0和4.x環(huán)境下,你可以使用Spring的 WebSphereTransactionManagerFactoryBean 類。這是一個工廠類,通過WebSphere的 靜態(tài)訪問方法(每個版本的WebSphere中都不同)獲取到JTA TransactionManager 實例。一旦通過工廠bean獲取到JTA TransactionManager 實例,就可以使用該實例裝配一個Spring的 JtaTransactionManager bean,它封裝了JTA UserTransaction,提供增強的事務語義。你可以按以下方式進行配置:

<bean id="wsJtaTm" class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager ref="wsJtaTm"/>①引用WebSphere的JTA事務管理器
</bean>

小結(jié)

你既可以在沒有任務應用服務器支持的情況下,直接通過集成JOTM在Spring中使用JTA事務管理,也可以通過引用Java EE應用服務器的JNDI數(shù)據(jù)源,利用應用服務器提供的JTA事務功能間接實現(xiàn)Spring 中的JTA事務管理。為了利用一些高級Java EE應用服務器的JTA事務高級功能,你可以通過Spring所提供的特定于應用服務器的JTA事務管理器進行配置

原文地址http://www.bieryun.com/1849.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結(jié)

以上是生活随笔為你收集整理的在Spring中使用JTA事务管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。