`
sundoctor
  • 浏览: 325441 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用atomikos在spring3、jpa2/hibernate4中实现JTA

阅读更多

公司使用ssh框架,近期因为项目使用到多数据源,web服务器为tomcat,为了数据的一致性,需要使用jta。在spring中使用jta现有两个主要的开源项目:jotm、atomikos。spring3中己移除了对jotm支持,所以只能使用atomikos,按照网上资料学习,将实践过程记录下来,以备参考。
1、atomikos需要的jar

transactions-3.9.0.M1.jar
transactions-api-3.9.0.M1.jar
transactions-hibernate3-3.9.0.M1.jar
transactions-jta-3.9.0.M1.jar
transactions-jdbc-3.9.0.M1.jar
atomikos-util-3.9.0.M1.jar



2、persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
	version="2.0">
	<!-- Keep this file empty, Spring will scan the @Entity classes -->
	<persistence-unit name="orcalePU" transaction-type="JTA">
	</persistence-unit>
	<persistence-unit name="mysqlPU" transaction-type="JTA">
	</persistence-unit>
</persistence>


persistence.xml很简单,定义两个持久化单元,类型为JTA

3、application.properties

mysql.databasePlatform=org.hibernate.dialect.MySQL5InnoDBDialect
mysql.jdbc.driver=com.mysql.jdbc.Driver
mysql.jdbc.url=jdbc:mysql://localhost:3306/post?useUnicode=true&characterEncoding=utf-8
mysql.jdbc.username=root
mysql.jdbc.password=kfs

#Oracle
oracle.databasePlatform=org.hibernate.dialect.Oracle10gDialect
oracle.jdbc.driver=oracle.jdbc.driver.OracleDriver
oracle.jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
oracle.jdbc.username=test
oracle.jdbc.password=kfs



application.properties中配置两个数据,oralce和mysql

4、applicationContext.xml

	<description>多数源JTA配置例子,本例子同时使用oracle、mysql数据同时提交、回滚事务</description>

	<!-- 使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 -->
	<context:component-scan base-package="com.techstar">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<context:property-placeholder
		ignore-resource-not-found="true" location="classpath*:/application.properties" />

	<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"
		proxy-target-class="true" />

	<!-- 定义aspectj -->
	<aop:aspectj-autoproxy proxy-target-class="true" />


	<!-- oracle 数据源配置 -->
	<bean id="oracleDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
		init-method="init" destroy-method="close">
		<property name="uniqueResourceName" value="oracleXADBMS" />
		<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
		<property name="xaProperties">
			<props>
				<prop key="user">${oracle.jdbc.username}</prop>
				<prop key="password">${oracle.jdbc.password}</prop>
				<prop key="URL">${oracle.jdbc.url}</prop>
			</props>
		</property>
		<property name="poolSize" value="2" />
		<property name="minPoolSize" value="1" />
		<property name="maxPoolSize" value="5" />
		<property name="testQuery" value="select 1 from dual" />
	</bean>
	<!-- AbstractTransactionalJUnit4SpringContextTests测试类需要一个名为 dataSource的数据源-->
	<alias name="oracleDataSource" alias="dataSource"/>

	<!-- Jpa Entity Manager 配置 -->
	<bean id="orcaleEntityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
		<property name="persistenceUnitName" value="orcalePU" />
		<property name="dataSource" ref="oracleDataSource" />
		<property name="jpaVendorAdapter" ref="oralceHibernateJpaVendorAdapter" />
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.connection.driver_class">oracle.jdbc.xa.client.OracleXADataSource</prop>
				<prop key="hibernate.current_session_context_class">jta</prop>
				<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
				</prop>
			</props>
		</property>
	</bean>

	<bean id="oralceHibernateJpaVendorAdapter"
		class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="databasePlatform">
			<value>${oracle.databasePlatform}</value>
		</property>
		<property name="showSql">
			<value>true</value>
		</property>
		<property name="generateDdl">
			<value>true</value>
		</property>
	</bean>


	<!-- Spring Data Jpa配置, 扫描base-package下所有继承于Repository<T,ID>的接口 -->
	<jpa:repositories base-package="com.techstar.topic.**.repository.jpa"		
		transaction-manager-ref="transactionManager"
		entity-manager-factory-ref="orcaleEntityManagerFactory" />


	<!-- mysql 数据源配置 -->
	<bean id="mysqlDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
		init-method="init" destroy-method="close">
		<property name="uniqueResourceName" value="mysqlXADBMS" />
		<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
		<property name="xaProperties">
			<props>
				<prop key="user">${mysql.jdbc.username}</prop>
				<prop key="password">${mysql.jdbc.password}</prop>
				<prop key="URL">${mysql.jdbc.url}</prop>
			</props>
		</property>
		<property name="poolSize" value="2" />
		<property name="minPoolSize" value="1" />
		<property name="maxPoolSize" value="5" />
		<property name="testQuery" value="select 1" />
	</bean>

	<!-- Jpa Entity Manager 配置 -->
	<bean id="mysqlEntityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
		<property name="persistenceUnitName" value="mysqlPU" />
		<property name="dataSource" ref="mysqlDataSource" />
		<property name="jpaVendorAdapter" ref="mysqlHibernateJpaVendorAdapter" />
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.connection.driver_class">com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</prop>
				<prop key="hibernate.current_session_context_class">jta</prop>
				<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
				</prop>
			</props>
		</property>
	</bean>

	<bean id="mysqlHibernateJpaVendorAdapter"
		class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="databasePlatform">
			<value>${mysql.databasePlatform}</value>
		</property>
		<property name="showSql">
			<value>true</value>
		</property>
		<property name="generateDdl">
			<value>true</value>
		</property>
	</bean>


	<!-- Spring Data Jpa配置, 扫描base-package下所有继承于Repository<T,ID>的接口 -->
	<jpa:repositories base-package="com.techstar.post.**.repository.jpa"		
		transaction-manager-ref="transactionManager"
		entity-manager-factory-ref="mysqlEntityManagerFactory" />



5、测试
oracle数据库实体类和dao类:

package com.techstar.topic.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.validator.constraints.NotBlank;

@Entity
@Table(name = "XA_TOPIC")
public class Topic {

        private String id;
	private String forumId;
	private String topicTitle;
	private String userId;
	private Date topicTime;
	private Integer topicViews;
	private Integer topicReplies;

	@Id	
	@GeneratedValue(generator = "system-uuid")// 主键自动生成策略:UUID
	@GenericGenerator(name = "system-uuid", strategy = "uuid")
	@Column(length=32)
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}

	@NotBlank
	@Column(length = 100)
	public String getForumId() {
		return forumId;
	}

	public void setForumId(String forumId) {
		this.forumId = forumId;
	}

	@NotBlank
	@Column(length = 200)
	public String getTopicTitle() {
		return topicTitle;
	}

	public void setTopicTitle(String topicTitle) {
		this.topicTitle = topicTitle;
	}

	@NotBlank
	@Column(length = 50)
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getTopicTime() {
		return topicTime;
	}

	public void setTopicTime(Date topicTime) {
		this.topicTime = topicTime;
	}

	public Integer getTopicViews() {
		return topicViews;
	}

	public void setTopicViews(Integer topicViews) {
		this.topicViews = topicViews;
	}

	public Integer getTopicReplies() {
		return topicReplies;
	}

	public void setTopicReplies(Integer topicReplies) {
		this.topicReplies = topicReplies;
	}

}



package com.techstar.topic.repository.jpa;

import org.springframework.data.jpa.repository.JpaRepository;

import com.techstar.topic.entity.Topic;

public interface TopicDao extends JpaRepository<Topic, String>{

}


项目使用了spring data jpa,dao类很简单,定义接口即可。

mysql对应的实体类和dao类

package com.techstar.post.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.validator.constraints.NotBlank;

@Entity
@Table(name = "XA_POST")
public class Post {

        private String id;
	private String topic;
	private String forumId;
	private String userId;
	private byte[] postAttach;
	private Date postTime;

	@Id	
	@GeneratedValue(generator = "system-uuid")// 主键自动生成策略:UUID
	@GenericGenerator(name = "system-uuid", strategy = "uuid")
	@Column(length=32)
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@NotBlank
	@Column(name = "TOPIC", length = 32)
	public String getTopic() {
		return topic;
	}

	public void setTopic(String topic) {
		this.topic = topic;
	}

	@NotBlank
	@Column(length = 100)
	public String getForumId() {
		return forumId;
	}

	public void setForumId(String forumId) {
		this.forumId = forumId;
	}

	@NotBlank
	@Column(length = 50)
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	@Lob
	public byte[] getPostAttach() {
		return postAttach;
	}

	public void setPostAttach(byte[] postAttach) {
		this.postAttach = postAttach;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getPostTime() {
		return postTime;
	}

	public void setPostTime(Date postTime) {
		this.postTime = postTime;
	}

}

 

package com.techstar.post.repository.jpa;

import org.springframework.data.jpa.repository.JpaRepository;

import com.techstar.post.entity.Post;

public interface PostDao extends JpaRepository<Post, String>{

}



junit单元测试类

package com.techstar.topic.service;

import java.util.Date;

import junit.framework.Assert;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.techstar.modules.utils.Identities;
import com.techstar.post.entity.Post;
import com.techstar.post.repository.jpa.PostDao;
import com.techstar.topic.entity.Topic;
import com.techstar.topic.repository.jpa.TopicDao;

@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class JTAServiceTest extends AbstractTransactionalJUnit4SpringContextTests {

	@Autowired
	private TopicDao topicDao;// oralce数据源
	@Autowired
	private PostDao postDao;// mysql数据源

	/**
	 * 单独俣存Topic到oracle数据库
	 */
	@Test
	public void saveTopic() {

		Topic topic = new Topic();
		topic.setForumId(Identities.uuid2());
		topic.setTopicReplies(5);
		topic.setTopicTime(new Date());
		topic.setTopicTitle(Identities.uuid2());
		topic.setTopicViews(2);
		topic.setUserId(Identities.uuid2());
		topicDao.save(topic);

		Assert.assertNotNull(topic.getId());
	}

	/**
	 * 单独俣存Post到mydql数据库
	 */
	@Test
	public void savePost() {

		Post post = new Post();
		post.setForumId(Identities.uuid2());
		post.setUserId(Identities.uuid2());
		post.setPostAttach(new String(Identities.uuid2()).getBytes());
		post.setPostTime(new Date());
		post.setTopic(Identities.uuid2());
		postDao.save(post);

		Assert.assertNotNull(post.getId());
	}

	/**
	 * 同时保存Topic到oracle数据库、Post到mydql数据库
	 */
	@Test
	public void saveTopicAndPostCommit() {

		Topic topic = new Topic();
		topic.setForumId(Identities.uuid2());
		topic.setTopicReplies(5);
		topic.setTopicTime(new Date());
		topic.setTopicTitle(Identities.uuid2());
		topic.setTopicViews(2);
		topic.setUserId(Identities.uuid2());
		topicDao.save(topic);

		Post post = new Post();
		post.setForumId(Identities.uuid2());
		post.setUserId(Identities.uuid2());
		post.setPostAttach(new String(Identities.uuid2()).getBytes());
		post.setPostTime(new Date());
		post.setTopic(topic.getId());
		postDao.save(post);

		Assert.assertNotNull(topic.getId());
		Assert.assertNotNull(post.getId());
	}

	/**
	 * Post回滚、Topic一起回滚
	 */
	@Test
	public void saveTopicAndPostRollback() {

		Topic topic = new Topic();
		topic.setForumId(Identities.uuid2());
		topic.setTopicReplies(5);
		topic.setTopicTime(new Date());
		topic.setTopicTitle(Identities.uuid2());
		topic.setTopicViews(2);
		topic.setUserId(Identities.uuid2());

		topicDao.save(topic);

		Post post = new Post();
		post.setForumId(null);// ForumId在数据设置不能为空,在这里设置为null,测试数据一起回滚
		post.setUserId(Identities.uuid2());
		post.setPostAttach(new String(Identities.uuid2()).getBytes());
		post.setPostTime(new Date());
		post.setTopic(topic.getId());

		postDao.save(post);

	}

	/**
	 * Topic回滚、Post一起回滚
	 */
	@Test(expected = ArithmeticException.class)
	public void saveTopicAndPostRollback2() {

		Post post = new Post();
		post.setForumId(Identities.uuid2());
		post.setUserId(Identities.uuid2());
		post.setPostAttach(new String(Identities.uuid2()).getBytes());
		post.setPostTime(new Date());
		post.setTopic(Identities.uuid2());

		postDao.save(post);

		Topic topic = new Topic();
		topic.setForumId(Identities.uuid2());
		topic.setTopicReplies(5);
		topic.setTopicTime(new Date());
		topic.setTopicTitle(Identities.uuid2());
		topic.setTopicViews(2);
		topic.setUserId(null);// UserId在数据设置不能为空,在这里设置为null,测试数据一起回滚

		topicDao.save(topic);

	}
}


最后运行单元测试,查看数据变化。

 

分享到:
评论
4 楼 a906910 2015-11-19  
有谁知道哪里有spring4 hibernate4 atomikos4 的
网上贴的都有问题 甚至连很多类型都是不存在的
3 楼 alex1960 2014-08-25  
sundoctor 您好:topicDao.saveAndFlush(topic); 报错,你的报错吗?


org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:157)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy37.saveAndFlush(Unknown Source)
at com.uleehub.cashcoupon.service.JTAServiceTest.saveTopicAndPostCommit(JTAServiceTest.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
at com.sun.proxy.$Proxy36.flush(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262)
at com.sun.proxy.$Proxy36.flush(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:405)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:373)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:344)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:329)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 36 more

org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: Transaction set to rollback only
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1024)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:597)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:296)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:189)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:416)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:91)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.transaction.RollbackException: Transaction set to rollback only
at com.atomikos.icatch.jta.TransactionImp.rethrowAsJtaRollbackException(TransactionImp.java:66)
at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:206)
at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:436)
at com.atomikos.icatch.jta.UserTransactionImp.commit(UserTransactionImp.java:107)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1021)
... 25 more
Caused by: com.atomikos.icatch.RollbackException: Transaction set to rollback only
at com.atomikos.icatch.imp.TxRollbackOnlyStateHandler.commit(TxRollbackOnlyStateHandler.java:76)
at com.atomikos.icatch.imp.CompositeTransactionImp.doCommit(CompositeTransactionImp.java:287)
at com.atomikos.icatch.imp.CompositeTerminatorImp.commit(CompositeTerminatorImp.java:77)
at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:336)
at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:190)
... 28 more
2 楼 sgq0085 2014-01-08  
我按照楼主的内容进行了尝试,但是失败了。
是否有基于Maven构建的DEMO可以提供参考?
1 楼 hackpro 2013-09-18  
非常好..
这几天我也在测试atom
不过我的环境是spring3.2+mybaits3.1+atom3.9

相关推荐

    spring-jta-atomikos:JTA,JPA,Hibernate和Atomikos的Spring项目

    标题中的“spring-jta-atomikos”是一个关于在Spring框架中使用JTA(Java Transaction API)和Atomikos的项目。JTA是Java平台中用于管理分布式事务的标准API,而Atomikos是一个开源的事务管理器,它支持JTA,并且在...

    Spring boot+Atomikos+JTA+Hibernate+mybatis+MySQL实现分布式事务+多数据源

    在本案例中,我们使用JPA与Hibernate集成,Hibernate作为JPA的实现,提供了更丰富的功能和性能优化。通过配置Spring Boot,我们可以轻松地将Hibernate整合到应用中,处理数据库的CRUD操作。 同时,MyBatis是一个轻...

    atomikos-jta-jpa-jms-example:带有 Spring、JPA 和 JMS 的 Atomikos JTA 示例

    本示例项目 "atomikos-jta-jpa-jms-example" 旨在演示如何在分布式环境中使用 Atomikos 进行事务管理,同时结合 Java Persistence API (JPA) 处理持久化数据,并通过 JMS 进行消息传递。 首先,我们来看 JTA(Java ...

    第二部分spring+hibernate+jta 分布式事务Demo

    Atomikos jta 的jar包 博文链接:https://momoko8443.iteye.com/blog/190994

    springboot-jpa atomikos 分布式事务管理

    本文将详细讲解"springboot-jpa atomikos 分布式事务管理"这一主题,以及如何在SpringBoot 2.0.5版本中结合JPA、Hibernate和MyBatis实现多数据库事务控制。 首先,SpringBoot是一个简化Spring应用开发的框架,它...

    atomikos-jta-camel-jpa-jms-example:带有 Camel、Spring、JPA 和 JMS 的 Atomikos JTA 示例

    - `pom.xml`:Maven 或 Gradle 的构建文件,定义了项目依赖,如 Atomikos、Spring、Camel、JPA 实现(如 Hibernate)和 JMS 提供商(如 ActiveMQ)。 - `src/main/java`:包含 Java 代码,如 Spring 配置类、Camel ...

    03_JPA详解_搭建JPA开发环境和全局事务介绍.zip

    2. **添加依赖**: 在Maven或Gradle项目中,需要引入JPA相关的依赖,比如Spring Data JPA、Hibernate等实现库。在Maven的pom.xml文件中,会包含如下依赖: ```xml &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; ...

    spring jpa

    Spring JPA(Java Persistence API)是 Spring 框架对 JPA 规范的集成,允许开发者在 Spring 应用中使用 ORM(对象关系映射)技术,如 Hibernate 或 EclipseLink。 Spring JPA 提供了以下核心功能: 1. **自动化...

    Spring事务类型祥解

    此外,Spring还提供了一种基于注解的回滚规则,即`@Rollback`注解,可以在测试中使用。 5. **Spring Boot中的事务管理**: 在Spring Boot项目中,通常使用`@EnableTransactionManagement`注解开启事务管理,并通过...

    spring-boot-reference.pdf

    4. Working with Spring Boot 5. Learning about Spring Boot Features 6. Moving to Production 7. Advanced Topics II. Getting Started 8. Introducing Spring Boot 9. System Requirements 9.1. Servlet ...

    Spring及其各

    3. **Spring管理Bean的原理**:在Spring中,Bean是被容器管理的对象,它们的实例化、初始化、装配以及销毁都由容器负责。Bean可以通过XML配置、注解或Java配置类进行定义。依赖注入是Spring管理Bean的主要方式,通过...

    springboot参考指南

    在Spring环境中使用YAML暴露属性 iii. 23.6.3. Multi-profile YAML文档 iv. 23.6.4. YAML缺点 vii. 23.7. 类型安全的配置属性 i. 23.7.1. 第三方配置 ii. 23.7.2. 松散的绑定(Relaxed binding) iii. 23.7.3. @...

    springTranction

    4. **事务传播行为**:在Spring中,@Transactional注解可以指定不同的传播行为,如REQUIRED(默认,如果当前存在事务则加入,否则新建)、REQUIRES_NEW(总是新建事务,如果已有事务则挂起)、SUPPORTS(如果有事务...

    SpringBoot启动器Starters使用及原理解析

    在本文中,我们介绍了Spring Boot的启动器Starters的使用和原理。Starters提供了许多有用的特性和功能,可以简化我们的开发过程,减少开发时间和成本。希望本文能够帮助大家更好地理解和使用Starters。

Global site tag (gtag.js) - Google Analytics