Spring Boot Hibernate Несколько источников данных и источников транзакций - PullRequest
0 голосов
/ 07 августа 2020

У нас есть приложение Spring Boot, которое должно взаимодействовать более чем с одной MYSQL базами данных с использованием Hibernate и c3p0

Сведения об имени базы данных:

  1. orderdb
  2. servicedb

И из 2 баз данных необходимо настроить (базу данных servicedb) для обработки большего количества запросов. Поэтому мы планируем реализовать концепцию Master (servicedb master) Slave (servicedb Slave).

Здесь наше требование состоит в том, чтобы разделить запрос на основе запроса

  • Если запрос основан на порядке, необходимо сохранить / получить его в / из orderdb.
  • Если к нашим службам поступает запрос на сохранение / обновление, и затем он должен быть перенаправлен на servicedb-master.
  • Если есть только запрос select к нашим службам, он должен быть перенаправлен на servicedb-slave.

У нас есть config.properties и файл Configuration XML, как показано ниже,

Config.properties

database.driverClassName = com. mysql. jdb c .Драйвер * 10 29 *

databaseservicedbmaster.url = jdb c: mysql: //127.0.0.1: 3306 / servicedb

databaseservicedbslave.url = jdb c: mysql: //192.16. 0.1: 3306 / servicedb

databaseorderdb.url = jdb c: mysql: //127.0.0.1: 3306 / orderdb

database.username = xxxxx

database.password = yyyyyy

hibernate.dialect = org.hibernate.dialect.MySQLDialect

hibernate.show_sql = false

hibernate.format_sql = false

hibernate.generate_statistics = false

spring. xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:sws="http://www.springframework.org/schema/web-services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       ">
       
<!-- Servicedb-Master DataBase Configuration -->

    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass"
            value="${database.driverClassName}"></property>
        <property name="jdbcUrl" value="${databaseservicedbmaster.url}"></property>
        <property name="user" value="${database.username}"></property>
        <property name="password" value="${database.password}"></property>
    </bean>
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan"
            value="com.services.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.event.merge.entity_copy_observer">allow</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager" primary="true">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- Servicedb-Slave DataBase Configuration -->
    <bean id="serviceDBSlavedataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass"
            value="${database.driverClassName}"></property>
        <property name="jdbcUrl" value="${databaseservicedbslave.url}"></property>
        <property name="user" value="${database.username}"></property>
        <property name="password" value="${database.password}"></property>
    </bean>
    <bean id="serviceDBSlaveSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="serviceDBSlavedataSource" />
        <property name="packagesToScan"
            value="com.services.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.event.merge.entity_copy_observer">allow</prop>
            </props>
        </property>
    </bean>
    <bean id="serviceDBSlaveTransactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="serviceDBSlaveSessionFactory" />
    </bean>


    <!-- Order DB DataBase Configuration -->
    
    <bean id="orderDBDataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass"
            value="${database.driverClassName}"></property>
        <property name="jdbcUrl" value="${databaseTwo.url}"></property>
        <property name="user" value="${database.username}"></property>
        <property name="password" value="${database.password}"></property>
    </bean>

    <bean id="orderDBSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="orderDBDataSource" />
        <property name="packagesToScan"
            value="com.orders.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.event.merge.entity_copy_observer">allow</prop>
            </props>
        </property>
    </bean>

    <bean id="orderDBTransactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="orderDBSessionFactory" />
    </bean>
</beans>

Вот реализация кода

Реализация Service API

@Service
public class ServiceImpl implements Iservice{

    @Autowired
    IOptimizedDoa optimizeddoa;

    @Override
    @Transactional("transactionManager")
    public String saveServices() {
        return optimizeddoa.saveServices();
    }
    
    @Override
    @Transactional("serviceDBSlaveTransactionManager")
    public String getServices() {
        return optimizeddoa.getServices();
    }
    
    
}

public class serviceDao implements IServiceDao{

@Autowired
private SessionFactory sessionFactory;

@Override
public String saveServices(){   

Services service= new Services();
service.setName("Test");
Session session = sessionFactory.getCurrentSession();
session.save(service);
return "Success";
}


@Override
public String getServices() {

Session session = sessionFactory.getCurrentSession();
String qry = "SELECT * FROM services where id='1'";
SQLQuery query2 = session.createSQLQuery(qry);
query2.addEntity(Services.class);
Services service = (List<Services>) query2.list().get(0);
return service.getname();;
}

}

Реализация кода API заказа

@Service
@Transactional("orderDBTransactionManager")
public class orderImpl implements Iorder{

    @Autowired
    IOrderDao orderDao;
    
    @Override
    public String getOrder() {
        return orderDao.get();
    }

}

public class orderDao implements IOrderDao{

@Autowired
private SessionFactory sessionFactory;


@Override
public String getOrder() {
        
Session session = sessionFactory.getCurrentSession();
String qry = "SELECT * FROM orders where id='1'";
SQLQuery query2 = session.createSQLQuery(qry);
query2.addEntity(Order.class);
Orders order = (List<Order>) query2.list().get(0);
return order.getname();;
}

Все службы запускаются должным образом.

Здесь, когда должен быть получен запрос заказы, все данные получают из базы данных заказов и работают должным образом. Обратите внимание, что мы аннотировали как @ Transactional ("orderDBTransactionManager") в классе обслуживания.

Но здесь проблема в том, что когда мы запрашиваем получение услуг, он должен получить данные из подчиненной базы данных, но она всегда получает дату от главной базы данных службы, хотя мы аннотировали как "@ Transactional (" serviceDBSlaveTransactionManager ")" .

Когда мы инициализируем фабрику сеансов для каждого источник данных работает, как ожидалось.

Мы не уверены, как это работает правильно, когда мы использовали для получения данных из базы данных заказов, используя @ Transactional ("orderDBTransactionManager") и то же самое, но не работает, когда мы аннотировали, чтобы получить данные из подчиненной базы данных "@ Transactional (" serviceDBSlaveTransactionManager ")".

Не могли бы вы сообщить нам, как поступить, чтобы получить данные из соответствующих обслуживаемых баз данных используя аннотацию @Transactional, как мы получаем данные из orderdb?

Будет ли наша реализация на правильно? или нам нужно инициализировать фабрику сеансов для каждого источника данных и использовать ее для получения данных, как показано ниже .?

   public class serviceDao implements IServiceDao{

@Autowired
@Qualifier("sessionFactory")
private SessionFactory serviceDbMastersessionFactory;

@Autowired
@Qualifier("serviceDBSlaveSessionFactory")
private SessionFactory serviceDbSlaveSessionFactory;

@Override
public String saveServices(){   

Services service= new Services();
service.setName("Test");
Session session = serviceDbMastersessionFactory.getCurrentSession();
session.save(service);
return "Success";
}


@Override
public String getServices() {

Session session = sessionFactory.getCurrentSession();
String qry = "SELECT * FROM services where id='1'";
SQLQuery query2 = serviceDbSlaveSessionFactory.createSQLQuery(qry);
query2.addEntity(Services.class);
Services service = (List<Services>) query2.list().get(0);
return service.getname();
}}

Пожалуйста, помогите нам реализовать это. Или есть лучший способ реализовать это?

Спасибо,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...