JTA can use one transaction on multiple databases. application servers such as WebLogic provide support for JTA data sources and can be directly used. However, Tomcat does not support this feature. To use JTA on Tomcat, you must use other tools. Jotm is an independent component that provides the JTA function.
Jotm is used in method 2. 1. JTA is provided in combination with the container's JNDI data source. 2. Use jotm to create a local data source. The following describes how to configure the first method.
Test environment:
Tomcat 6.0.18
MySQL 5.1.47
Jotm 2.0.10
Spring 3.0.0 RC3
Hibernate 3.1.3
1: Add jotm jar
Place the jotm JAR file, database JDBC driver, and related class libraries in % catalina_home %/lib.
Commons-logging.jar
Log4j. Jar
Commons-cli-1.0.jar
Connector-1_5.jar
Howl. Jar
Jotm. Jar
Jotm_iiop_stubs.jar
Jotm_jrmp_stubs.jar
Jta-spec1_0_1.jar
Jts00000.jar
Objectweb-datasource.jar
Ow_carol.jar
Xapool. Jar
Note:
1: common-logging.jar and log4j. Jar also need to be copied, and make sure the specific application does not contain the two files.
2: The application cannot contain JTA. jar, which conflicts with the jta-spec1_0_1.jar under the Tomcat public class path.
3: % catalina_home %/lib is the public class path of Tomcat. jar,. class, or. properties files can be stored in this directory and can be accessed by all applications.
2: Create the Carol. properties configuration file.
Create Carol. properties and put it under % catalina_home %/lib (the jar or class files in this directory can be accessed by all applications ). The contents of the Carol. properties configuration file are as follows: # JNDI Call Protocol Carol. Protocols = jrmp # The local RMI call must be set to false. Otherwise, an exception occurs during the program running. Carol. JVM. RMI. Local. Call = false # Do not use Carol's JNDI wrappers Carol. Start. JNDI = false # Disable naming Server Carol. Start. NS = false # Naming factory class Carol. JNDI. java. Naming. Factory. url. pkgs = org. Apache. Naming |
Note:
Carol. JVM. RMI. Local. call must be set to false. Otherwise, the following error will be reported during running:
Java. Lang. nosuchmethoderror: Sun. RMI. Transport. objecttable. getstub (ljava/RMI/remote;) ljava/RMI/Server/remotestub
3: configure the JNDI Data Source
3.1 Add the following content to the <context> </context> label of % catalina_home %/CONF/context. xml:
<! -Data Source 1 -->
<Resource Name = "JDBC/edit" auth = "Container" type = "javax. SQL. datasource"
Factory = "org. objectweb. JNDI. performancefactory"
Driverclassname = "com. p6spy. Engine. Spy. p6spydriver" username = "root"
Password = "007" url = "JDBC: mysql: // localhost: 3306/edit"/>
<! -Data Source 2 -->
<Resource Name = "JDBC/test" auth = "Container" type = "javax. SQL. datasource"
Factory = "org. objectweb. JNDI. performancefactory"
Driverclassname = "org. gjt. Mm. MySQL. Driver" username = "root"
Password = "007" url = "JDBC: mysql: // localhost: 3306/test"/>
<! -Usertransaction -->
<Transaction factory = "org. objectweb. jotm. usertransactionfactory" jotm. Timeout = "60"/>
Note: factory = "org. objectweb. JNDI. datasourcefactory "specifies the factory for creating the data source. If this row is omitted, the data source can still be created, but the data source provided by tomcat6 is created, instead of the data source implementation of jotm, JTA transactions cannot be satisfied.
3.2 reference the global data source and create context. xml under the META-INF of the application, the file content is as follows
<Context>
<Watchedresource> WEB-INF/Web. xml </watchedresource>
<Resourcelink global = "JDBC/edit" name = "JDBC/edit" type = "javax. SQL. datasource"/>
<Resourcelink global = "JDBC/test" name = "JDBC/test" type = "javax. SQL. datasource"/>
<! -- Resourcelink name = "usertransaction" Global = "usertransaction" type = "javax. transaction. usertransaction"/-->
</Context>
4. Configure the spring Data Source
<? XML version = "1.0" encoding = "UTF-8"?>
<! -- ===================================================== ========================================================== ============================ -->
<! -->
<! -- Data source -->
<! -- Use aotm to implement JTA transactions and multiple data sources -->
<! -- ===================================================== ========================================================== ============================ -->
<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"
>
<! -- Property loader -->
<Bean id = "propertyconfigurer"
Class = "org. springframework. Beans. Factory. config. propertyplaceholderconfigurer">
<Property name = "location" value = "classpath: spring/config. properties"/>
</Bean>
<! -- Search for a data source -->
<Jee: JNDI-lookup id = "ds_edit" JNDI-name = "Java: COMP/ENV/jdbc/edit"/>
<Jee: JNDI-lookup id = "ds_test" JNDI-name = "Java: COMP/ENV/jdbc/test"/>
<! -- Jee: JNDI-lookup id = "usertransaction" JNDI-name = "usertransaction"/-->
<! -- JTA Transaction Manager -->
<Bean id = "txmanager" class = "org. springframework. transaction. JTA. jtatransactionmanager"/>
<! -- TX: annotation-driven transaction-Manager = "txmanager"/-->
<! -- [Automatic transaction proxy] Interceptor -->
<Bean id = "servicetransactioninterceptor"
Class = "org. springframework. transaction. Interceptor. transactioninterceptor">
<Property name = "transactionmanager" ref = "txmanager"/>
<Property name = "transactionattributes">
<Props>
<Prop key = "*"> propagation_required,-exception </prop>
</Props>
</Property>
</Bean>
<! -- [Automatic transaction proxy] producer to convert all * Service beans into transaction beans -->
<Bean class = "org. springframework. AOP. Framework. autoproxy. beannameautoproxycreator">
<Property name = "beannames">
<Value> * service </value>
</Property>
<Property name = "interceptornames">
<List>
<Value> servicetransactioninterceptor </value>
</List>
</Property>
</Bean>
<! -- Hibernate factory -->
<Bean id = "sessionfactory1" class = "org. springframework. Orm. hibernate3.localsessionfactorybean">
<Property name = "datasource"> <ref bean = "ds_edit"/> </property>
<Property name = "hibernateproperties">
<Props>
<Prop key = "hibernate. show_ SQL"> true </prop>
<Prop key = "hibernate. dialect"> org. hibernate. dialect. oracle9dialect </prop>
<Prop key = "hibernate. query. factory_class"> org. hibernate. hql. Ast. astquerytranslatorfactory </prop>
</Props>
</Property>
<Property name = "mappingresources">
<List>
<Value> COM/aisidi/edit/entity/HBM/dog. HBM. xml </value>
</List>
</Property>
</Bean>
<! -- Hibernate factory 2 -->
<Bean id = "sessionfactory2" class = "org. springframework. Orm. hibernate3.localsessionfactorybean">
<Property name = "datasource"> <ref bean = "ds_test"/> </property>
<Property name = "hibernateproperties">
<Props>
<Prop key = "hibernate. show_ SQL"> true </prop>
<Prop key = "hibernate. dialect"> org. hibernate. dialect. oracle9dialect </prop>
<Prop key = "hibernate. query. factory_class"> org. hibernate. hql. Ast. astquerytranslatorfactory </prop>
</Props>
</Property>
<Property name = "mappingresources">
<List>
<Value> COM/aisidi/edit/entity/HBM/cat. HBM. xml </value>
</List>
</Property>
</Bean>