天天看點

Tomcat 結合Atomikos 實作JTA

Tomcat下配置Atomikos實作JTA

         Tomcat作為一款經典的Web伺服器,在開發、測試和生産環境中得到了廣泛的使用。但Tomcat畢竟不是Java EE伺服器,是以在EJB,JTA方面并沒有提供支援。本文講述了Tomcat使用Atomikos實作JTA的一種方法。

         在Tomcat中使用JTA,可以将Atomikos部署在Tomcat中,使用Tomcat支援的資料源;也可以在項目中配置,利用Spring配置好資料源、連接配接池、事務管理器等等。兩種方式各有特點,本文隻介紹Tomcat與Atomikos的內建,內建後Tomcat可以對外提供JTA的事務管理器和資料源。

         在使用Atomikos之前,我們也曾使用過JOTM,不過在高并發的情況下,JOTM頻頻出錯,最後不得不放棄,通過測試,發現Atomikos性能和穩定性都不錯。

         我們使用了Atomikos最新的4.04版本,Jar包的擷取可以從maven的配置庫中得到,連結位址:http://mvnrepository.com/artifact/com.atomikos

         如果不使用Hibernate,需要的包包括:

atomikos-util.jar,jta.jar,transactions.jar,transactions-api.jar,transactions-jdbc.jar,

transactions-jta.jar

配置步驟如下:

Step 1:将這些jar 拷貝到tomcat 的lib 目錄中。要實作Tomcat與Atomikos內建,還需要一個內建包,這個內建包裡面有兩個class,可以自己參考實作,也可以使用官方提供的jar包,最新的是atomikos-integration-extension-3.7.2.jar

Step2:在tomcat/config/server.xml中 增加一個監聽器

  <Listener className="com.atomikos.tomcat.AtomikosLifecycleListener" />

Step3:在tomcat/config/context.xml中增加資料源和相關的事務管理器,下面是一個參考的例子,參數酌情修改

  <Resource name="jdbc/DS_MYSQL"

            auth="Container"

            type="com.atomikos.jdbc.AtomikosDataSourceBean"

            uniqueResourceName="jdbc/DS_MYSQL"

            xaDataSourceClassName="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"

            xaProperties.databaseName="db_test"

            xaProperties.serverName="localhost"

            xaProperties.port="3306"

            xaProperties.user="root"

            xaProperties.password="root"

            maxPoolSize="200"

            xaProperties.url="jdbc:mysql://localhost:3306/db_test?characterEncoding=UTF8"

            factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" />

  <Resource name="UserTransaction"

            auth="Container"

            type="javax.transaction.UserTransaction" />   

   <Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" /> 

Step4:在tomcat/lib目錄下增加一個jta.properties檔案,設定Atomikos事務相關的參數,否則将使用預設的配置參數,一些并發事務數(預設50個),逾時時間等都需要調整,下面給出了檔案中的一些參數配置,參數解釋請查閱官方文檔:https://www.atomikos.com/Documentation/JtaProperties

# SAMPLE PROPERTIES FILE FOR THE TRANSACTION SERVICE

# THIS FILE ILLUSTRATES THE DIFFERENT SETTINGS FOR THE TRANSACTION MANAGER

# UNCOMMENT THE ASSIGNMENTS TO OVERRIDE DEFAULT VALUES;

# Required: factory implementation class of the transaction core.

# NOTE: there is no default for this, so it MUST be specified!

#

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory

# Set base name of file where messages are output

# (also known as the 'console file').

#

# com.atomikos.icatch.console_file_name = tm.out

# Size limit (in bytes) for the console file;

# negative means unlimited.

#

# com.atomikos.icatch.console_file_limit=-1

# For size-limited console files, this option

# specifies a number of rotating files to

# maintain.

#

# com.atomikos.icatch.console_file_count=1

# Set the number of log writes between checkpoints

#

# com.atomikos.icatch.checkpoint_interval=500

# Set output directory where console file and other files are to be put

# make sure this directory exists!

#

# com.atomikos.icatch.output_dir = ./

# Set directory of log files; make sure this directory exists!

#

# com.atomikos.icatch.log_base_dir = ./

# Set base name of log file

# this name will be  used as the first part of

# the system-generated log file name

#

# com.atomikos.icatch.log_base_name = tmlog

# Set the max number of active local transactions

# or -1 for unlimited.

#

# com.atomikos.icatch.max_actives = 50

# Set the default timeout (in milliseconds) for local transactions

#

# com.atomikos.icatch.default_jta_timeout = 10000

# Set the max timeout (in milliseconds) for local transactions

#

# com.atomikos.icatch.max_timeout = 300000

# The globally unique name of this transaction manager process

# override this value with a globally unique name

#

# com.atomikos.icatch.tm_unique_name = tm

# Do we want to use parallel subtransactions? JTA's default

# is NO for J2EE compatibility

#

# com.atomikos.icatch.serial_jta_transactions=true

# If you want to do explicit resource registration then

# you need to set this value to false.

#

# com.atomikos.icatch.automatic_resource_registration=true 

# Set this to WARN, INFO or DEBUG to control the granularity

# of output to the console file.

#

# com.atomikos.icatch.console_log_level=WARN

# Do you want transaction logging to be enabled or not?

# If set to false, then no logging overhead will be done

# at the risk of losing data after restart or crash.

#

# com.atomikos.icatch.enable_logging=true

# Should two-phase commit be done in (multi-)threaded mode or not?

# Set this to false if you want commits to be ordered according

# to the order in which resources are added to the transaction.

#

# NOTE: threads are reused on JDK 1.5 or higher.

# For JDK 1.4, thread reuse is enabled as soon as the

# concurrent backport is in the classpath - see

# http://mirrors.ibiblio.org/pub/mirrors/maven2/backport-util-concurrent/backport-util-concurrent/

#

# com.atomikos.icatch.threaded_2pc=false

# Should shutdown of the VM trigger shutdown of the transaction core too?

#

# com.atomikos.icatch.force_shutdown_on_vm_exit=false

         Atomikos中參數的預設值在transactions.jar中定義,transactions-default.properties,具體參數如下:

com.atomikos.icatch.enable_logging=true

com.atomikos.icatch.force_shutdown_on_vm_exit=false

com.atomikos.icatch.automatic_resource_registration=true

com.atomikos.icatch.checkpoint_interval=500

com.atomikos.icatch.serial_jta_transactions=true

com.atomikos.icatch.default_jta_timeout=10000

com.atomikos.icatch.max_timeout=300000

com.atomikos.icatch.log_base_dir=./

com.atomikos.icatch.threaded_2pc=false

com.atomikos.icatch.max_actives=50

com.atomikos.icatch.log_base_name=tmlog

java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory

com.atomikos.icatch.client_demarcation=false

java.naming.provider.url=rmi://localhost:1099

com.atomikos.icatch.rmi_export_class=none

com.atomikos.icatch.trust_client_tm=false

com.atomikos.icatch.forget_orphaned_log_entries_delay=86400000

com.atomikos.icatch.recovery_delay=${com.atomikos.icatch.default_jta_timeout}

com.atomikos.icatch.oltp_max_retries=5

com.atomikos.icatch.oltp_retry_interval=10000

com.atomikos.icatch.allow_subtransactions=true

         配置完以上四個步驟,Tomcat的內建就算完成了,項目中可以使用Spring來關聯資料源和事務管理器,參考配置如下:

     <!-- JNDI模闆配置資訊,用于連接配接應用伺服器-->

    <bean class="org.springframework.jndi.JndiTemplate" id="jndiTemplate" />

    <!--引用Tomcat資料源-->

    <bean class="org.springframework.jndi.JndiObjectFactoryBean" id="dataSource">

        <property name="jndiName">

            <value>java:comp/env/jdbc/DS_MYSQL</value>

        </property>

        <property name="jndiTemplate">

            <ref bean="jndiTemplate"/>

        </property>

    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

        <property name="dataSource">

            <ref bean="dataSource" />

        </property>

    </bean>  

    <!--使用者事務對象-->

    <bean class="org.springframework.jndi.JndiObjectFactoryBean" id="userTransaction">

        <!--class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">-->

        <property name="jndiName">

            <value>java:comp/UserTransaction</value>

        </property>

        <property name="jndiTemplate">

            <ref bean="jndiTemplate"/>

        </property>

    </bean>

    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"

        init-method="init" destroy-method="close">

        <property name="forceShutdown" value="false" />

    </bean>

    <!-- 配置基于注解的聲明式事務管理器 -->

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">

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

        <property name="transactionManager" ref="atomikosTransactionManager" />

    </bean> 

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

         在Tomcat配置中使用的XA的資料源和JDBC驅動,應該可以使用nonXA的相關設定,Atomikos中也支援非XA的連接配接,以提高運作速度。關于nonXa的資料源,可以參考一下配置:

<Resource name="jdbc/DS_MYSQL"

            auth="Container"

            type="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean"

            uniqueResourceName="jdbc/DS_MYSQL"

            driverClassName="com.mysql.jdbc.Driver"

            maxPoolSize="200"

            url="jdbc:mysql://localhost:3306/db_test?characterEncoding=UTF8"

            user="root"

            password="root"

            factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" /> 

本文中的内容參考官方文檔整理:細節請查閱

https://www.atomikos.com/Documentation/Tomcat7Integration35