公司要上一个新项目,功能不多,并发访问不少,而且规划带有社交功能,所以数据量也不少。考虑这些情况,在做架构的时候,对web服务器进行了集群架构,对数据库也进行了集群、分库架构。
项目web服务器没有采用支持j2ee容器的jboss,weblogic等,而是tomcat+nginx架构,这样问题来了。我们都知道,tomcat这一类的web容器,只支持RESOURCE_LOCAL事务,对JTA事务是不支持的(这两个事务管理器的区别,见:http://brushupo.blog.sohu.com/95340446.html),报异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: NewPersistenceUnit] Unable to build EntityManagerFactory
......
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: NewPersistenceUnit] Unable to build EntityManagerFactory
......
Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
......
为了解决这个问题,在项目中引入了开源项目atomikos,实现如下:
1、通过maven下载atomikos程序jar包;
pos.xml(http://blog.sina.com.cn/s/blog_7035c6ac0101hs3u.html)
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atomikos</groupId>
<artifactId>atomikos-libs</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>atomikos-libs MavenWebapp</name>
<url>http://maven.apache.org</url>
<properties>
<atomikos-version>3.9.1</atomikos-version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>atomikos-util</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-api</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-hibernate2</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-hibernate3</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jms</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-osgi</artifactId>
<version>${atomikos-version}</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-eclipselink</artifactId>
<version>${atomikos-version}</version>
</dependency>
</dependencies>
<build>
<finalName>atomikos-libs</finalName>
</build>
</project>
执行下载得到jar包:mvn -f pom.xml dependency:copy-dependencies
2、项目采用spring3+hibernate3+jpa2的结构,在项目中进行配置如下:
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="NewPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="****" />
<property name="hibernate.connection.url" value="jdbc:mysql://ip:3306/数据库名?useUnicode=true&characterEncoding=UTF-8" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.maxActive" value="10"></property>
<property name="hibernate.maxIdle" value="30"></property>
<property name="hibernate.maxWait" value="10"></property>
<property name="javax.persistence.validation.mode" value="none"/>
<property name="hibernate.current_session_context_class" value="jta" />
<property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">
<context:annotation-config />
<context:component-scan base-package="xq.cy"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- <property name="dataSource" ref="dataSource" /> -->
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="database" value="MYSQL" />
</bean>
</property>
<property name="persistenceUnitName" value="NewPersistenceUnit" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="true" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
<!-- 启用 annotation事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
其他关于mvc,web.xml的配置不一一列出,程序在tomcat下运行,支持jta事务管理,大公告成。
参考:http://sundoctor.iteye.com/blog/1928279