`
hongfu951
  • 浏览: 2748 次
  • 性别: Icon_minigender_1
  • 来自: 贵阳
最近访客 更多访客>>
社区版块
存档分类
最新评论

spring boot,JPA和Atomikos实现分布式事务

阅读更多

一、实例描述和实体模型

     我们想在同一时间两个不同的数据库保存两个实体,这个操作需要事务。因此,在这个例子中,我们有一个Customer实体,它将第一个持久化到数据库中,而Order实体将被持久化到第二个数据库中。这两个实体非常简单,这个实例仅仅是一个示范。



这个结果实现如下:值得注意的是,它是属于两个不同的包,原因有两点:

1、项目呈现上下级逻辑分离的

2、每一个repository将扫描包含实体的包,并且进行管理。



package com.at.mul.domain.customer;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Entity
@Table(name = "customer")
@Data
@EqualsAndHashCode(exclude = { "id" })
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Column(name = "name", nullable = false)
private String name;

@Column(name = "age", nullable = false)
private Integer age;

}

package com.at.mul.domain.order;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Entity
@Table(name = "orders")
@Data
@EqualsAndHashCode(exclude = { "id" })
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Column(name = "code", nullable = false)
private Integer code;

@Column(name = "quantity", nullable = false)
private Integer quantity;

}

对于注解@Data和@EqualsAndHashCode请看Lombok



二、写repositories接口

在这个事例中它是一个标准,这里是需要注意的是我写了两个接口在两个不同的包,这个原因在下一个步骤将会解释:

package com.at.mul.repository.customer;

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

import com.at.mul.domain.customer.Customer;

public interface CustomerRepository extends JpaRepository<Customer, Integer> {

}

package com.at.mul.repository.order;

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

import com.at.mul.domain.order.Order;

public interface OrderRepository extends JpaRepository<Order, Integer> {

}
三、写配置类:

     这里有一点有兴趣的事,@DependsOn("transactionManager")注解不是强制的,但是在测试启动时我需要去掉若干的警告,像logs里面的WARNING: transaction manager not running?。下一个注解@EnableJpaRepositories才是重要的。

1、情况一是对于注解组件进行包扫描(repository接口),并且在我的实例中,我想仅仅repositories

customer (相反的就是repositories order)

2、情况二是实体管理者去管理实体,在我的实例中,customerEntityManager管理customer相关操作并且orderEntityManager管理order的相关操作

3、情况三是事务管理器被使用,在我的实例中transactionManager定义在MainConfig类中。这是需要对于每一个@EnableJpaRepositories 获取的工作事务都是同一个。

package com.at.mul;

import java.util.HashMap;

import javax.sql.DataSource;

import org.h2.jdbcx.JdbcDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import com.at.mul.repository.customer.CustomerDatasourceProperties;
import com.atomikos.jdbc.AtomikosDataSourceBean;

@Configuration
@DependsOn("transactionManager")
@EnableJpaRepositories(basePackages = "com.at.mul.repository.customer", entityManagerFactoryRef = "customerEntityManager", transactionManagerRef = "transactionManager")
@EnableConfigurationProperties(CustomerDatasourceProperties.class)
public class CustomerConfig {

@Autowired
private JpaVendorAdapter jpaVendorAdapter;

@Autowired
private CustomerDatasourceProperties customerDatasourceProperties;

@Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")
public DataSource customerDataSource() {
JdbcDataSource h2XaDataSource = new JdbcDataSource();
h2XaDataSource.setURL(customerDatasourceProperties.getUrl());

AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(h2XaDataSource);
xaDataSource.setUniqueResourceName("xads1");
return xaDataSource;
}

@Bean(name = "customerEntityManager")
@DependsOn("transactionManager")
public LocalContainerEntityManagerFactoryBean customerEntityManager() throws Throwable {

HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
properties.put("javax.persistence.transactionType", "JTA");

LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setJtaDataSource(customerDataSource());
entityManager.setJpaVendorAdapter(jpaVendorAdapter);
entityManager.setPackagesToScan("com.at.mul.domain.customer");
entityManager.setPersistenceUnitName("customerPersistenceUnit");
entityManager.setJpaPropertyMap(properties);
return entityManager;
}

}

package com.at.mul;

import java.util.HashMap;

import javax.sql.DataSource;

import org.h2.jdbcx.JdbcDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import com.at.mul.repository.order.OrderDatasourceProperties;
import com.atomikos.jdbc.AtomikosDataSourceBean;

@Configuration
@DependsOn("transactionManager")
@EnableJpaRepositories(basePackages = "com.at.mul.repository.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager")
@EnableConfigurationProperties(OrderDatasourceProperties.class)
public class OrderConfig {

@Autowired
private JpaVendorAdapter jpaVendorAdapter;

@Autowired
private OrderDatasourceProperties orderDatasourceProperties;

@Bean(name = "orderDataSource", initMethod = "init", destroyMethod = "close")
public DataSource orderDataSource() {
JdbcDataSource h2XaDataSource = new JdbcDataSource();
h2XaDataSource.setURL(orderDatasourceProperties.getUrl());

AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(h2XaDataSource);
xaDataSource.setUniqueResourceName("xads2");
return xaDataSource;
}

@Bean(name = "orderEntityManager")
public LocalContainerEntityManagerFactoryBean orderEntityManager() throws Throwable {

HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
properties.put("javax.persistence.transactionType", "JTA");

LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setJtaDataSource(orderDataSource());
entityManager.setJpaVendorAdapter(jpaVendorAdapter);
entityManager.setPackagesToScan("com.at.mul.domain.order");
entityManager.setPersistenceUnitName("orderPersistenceUnit");
entityManager.setJpaPropertyMap(properties);
return entityManager;
}

}

另一个重要的事,这里LocalContainerEntityManagerFactoryBean的定义:

1、@bean注解有获取一个name,他是在@EnableJpaRepositories注解中进行指定的。

2、你需要设置一些属性到JpaPropertyMap中,详细的说,你需要标注transaction是JTA和JTA平台是AtomikosJtaPlatform.class.getName()

我的实例不能正常执行的就是我为什么不设置第二个属性的原因。Dave Syer写道"我看了Atomikos范围之外Hibernate4不能工作",因此你需要实现类去设置hibernate.transaction.jta.platform属性,依我看来,这不是一个很好的文档,但是庆幸Oliver Gierke发现了另一个关于这个标题的文章 StackOverflow discussion 。如果你是用的是另一个JTA提供者,这个可能对你有用this useful.

注意:文章到这里还没有完,由于篇幅限制,完整内容请到hongfu951博客上查看

完整内容URL地址:用多数据库spring boot,spring data JPA和Atomikos实现分布式事务

 

分享到:
评论

相关推荐

    Springboot+Atomikos+Jpa+Mysql实现JTA分布式事务

    本文将详细讲解如何利用Spring Boot、Atomikos、JPA(Java Persistence API)以及MySQL来实现JTA(Java Transaction API)分布式事务。 首先,Spring Boot是一个轻量级的框架,它简化了基于Spring的应用程序开发...

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

    4. 配置Atomikos事务管理器,使Spring Boot应用支持JTA事务。 5. 在需要处理分布式事务的服务类或方法上添加@Transactional注解。 6. 编写业务代码,根据需求调用两个数据源的DAO层方法。 通过上述步骤,我们能够在...

    spring-boot-atomikos.rar

    综上所述,"spring-boot-atomikos.rar"是一个关于Spring Boot集成Atomikos实现分布式事务的综合资源,包含理论知识、代码实践和源码解析,对于理解和应用分布式事务具有很高的价值。通过学习这个资源,开发者将能更...

    分布式事务管理SpringBoot集成Atomikos使用Oracle数据库mybatis、jta框架.rar

    SpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatis

    Springboot 动态多数据源 jta分布式事务

    本资源针对的是Spring Boot动态多数据源和JTA(Java Transaction API)分布式事务的实现,对于初学者来说非常实用。下面我们将深入探讨这些知识点。 首先,让我们了解一下Spring Boot的多数据源。在许多业务场景下...

    springboot多数据源即分布式事务解决方案

    总之,SpringBoot通过其灵活的配置和强大的事务管理能力,为开发者提供了实现多数据源和分布式事务的有效工具。在实际项目中,我们需要根据具体业务场景选择合适的数据源策略和事务管理方式,确保系统的稳定性和数据...

    springboot多数据源即分布式事务解决方案,添加对多线程的支持

    Spring Boot结合Spring Framework中的`PlatformTransactionManager`接口和`@Transactional`注解,可以方便地实现分布式事务管理。通常,我们可以使用`JtaTransactionManager`配合Atomikos、Bitronix等JTA实现来处理...

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

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

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

    1. **JTA事务管理**: 配置Spring Boot以使用JTA事务管理,需要引入`spring-boot-starter-jta-atomikos`或`spring-boot-starter-jta-bitronix`依赖,并配置相应的事务管理器。 2. **Atomikos和Bitronix**: Atomikos...

    Spring-Boot-Game是基于SpringBoot+SpringCloud的开发系统

    5. 分布式事务:Seata或Atomikos等工具处理分布式环境下的事务一致性问题。 6. 日志管理:ELK(Elasticsearch、Logstash、Kibana)堆栈或Fluentd等日志收集和分析,便于故障排查。 7. Docker容器化:使用Docker和...

    SpringBoot+Atomikos+动态多数据源+事务+2种切换数据源的方式

    在Spring Boot的配置文件(application.properties或yaml)中,设置Atomikos的属性,如事务超时时间、回滚策略等。同时,需要创建一个`UserTransaction`的@Bean,这样Spring就能识别并使用Atomikos进行事务管理。 3...

    springboot整合jta实现多数据源事务管理

    在Spring Boot应用中,整合JTA(Java Transaction API)实现多数据源事务管理是一个常见的需求,特别是在分布式系统中,为了确保数据的一致性和完整性。本文将深入探讨如何配置和使用Spring Boot与JTA来管理多个...

    spring-boot-reference.pdf

    Spring Boot Documentation 1. About the Documentation 2. Getting Help 3. First Steps 4. Working with Spring Boot 5. Learning about Spring Boot Features 6. Moving to Production 7. Advanced Topics II. ...

    dynamic-datasource-spring-boot-starter-master.zip

    `dynamic-datasource-spring-boot-starter-master.zip` 提供了一个基于SpringBoot的动态数据源解决方案,能够帮助开发者快速实现多数据源的管理和切换。 首先,我们来理解一下什么是动态数据源。动态数据源是指在...

    Spring事务类型祥解

    此外,Spring还提供了`Atomikos`和`Bitronix`这样的第三方事务管理器来实现全局事务。 7. **事务的边界**: 正确地设定事务边界至关重要,这决定了事务开始和结束的时机。在服务层或DAO层的方法上添加`@...

    SpringBoot 25道面试题和答案.docx

    在微服务架构中,面对分布式事务的挑战,SpringBoot提供了与Atomikos等分布式事务管理器的集成。然而,由于分布式事务可能带来的性能影响,实践中通常倾向于采用补偿性事务管理,即通过消息队列的回溯机制来保证事务...

    初始化的单体流程引擎 camunda

    - 对于生产环境,考虑使用分布式事务管理器,如Atomikos或Bitronix,以保证数据一致性。 - 部署过程中可能遇到权限问题,确保用户角色和权限设置正确。 - 为了提高性能,可以使用缓存技术,如Hazelcast,来缓存流程...

    springboot参考指南

    使用一个Atomikos事务管理器 ii. 32.2. 使用一个Bitronix事务管理器 iii. 32.3. 使用一个J2EE管理的事务管理器 iv. 32.4. 混合XA和non-XA的JMS连接 v. 32.5. 支持可替代的内嵌事务管理器 xii. 33. Spring集成 xiii....

    springboot学习思维笔记.xmind

    spring-boot-starter-jta-atomikos spring-boot-starter-jta-bitronix spring-boot-starter-mail spring-boot-starter-mobile spring-boot-starter-mustache spring-boot-starter-...

Global site tag (gtag.js) - Google Analytics