java - 如何仅将特定数据库用于托管操作

标签 java spring jpa mbeans

我们使用spring和jpa 2.0 我有托管 bean,它们调用与客户端相同的方法。 我希望托管 bean 在从属数据库上运行,而客户端在主数据库上调用。

知道如何做到这一点吗?

谢谢

Here is my xml file defining datasources :

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- connection pool datasource which supports also XA 2 phase commit -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

    <property name="url" value="jdbc:mysql://localhost:3306/netoplay"/>
    <property name="username" value="root" />
    <property name="password" value="" />

    <property name="initialSize" value="10"/>
    <property name="maxActive" value="100"/> <!-- The maximum number of active connections that can be allocated from this pool at the same time, or negative for no limit. -->
    <property name="maxIdle" value="15"/> <!-- The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit. -->
    <property name="minIdle" value="10"/> <!-- The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none. -->
    <property name="timeBetweenEvictionRunsMillis" value="10000"/> <!-- the idle evicter thread evicts idle connections -->
    <property name="minEvictableIdleTimeMillis" value="60000"/> <!-- time a connection may be idle until it can be evicted -->

    <property name="validationQuery" value="/* ping */ SELECT 1"/>
    <property name="testOnBorrow" value="true"/> <!-- test the connection using the ping validationQuery before it is given to the application -->
    <property name="testWhileIdle" value="true"/> <!-- in addition to testOnBorrow, test connections while they are sitting idle -->

    <!-- If you enable "removeAbandoned" then it is possible that a connection is reclaimed by the pool because it is considered to be abandoned. This mechanism is triggered when (getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3) -->
    <property name="removeAbandoned" value="true"/> <!-- Flag to remove abandoned connections if they exceed the removeAbandonedTimout. If set to true a connection is considered abandoned and eligible for removal if it has been idle longer than the removeAbandonedTimeout. Setting this to true can recover db connections from poorly written applications which fail to close a connection. -->
    <property name="removeAbandonedTimeout" value="300"/> <!-- Timeout in seconds before an abandoned connection can be removed. 300 seconds (5 minutes) is the default -->

</bean>

<bean id="dataSourceSlaveDB" class="org.apache.commons.dbcp.BasicDataSource"> <!-- connection pool datasource which supports also XA 2 phase commit -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

    <property name="url" value="jdbc:mysql://localhost:3306/netoplay"/>
    <property name="username" value="root" />
    <property name="password" value="" />

    <property name="initialSize" value="10"/>
    <property name="maxActive" value="100"/> <!-- The maximum number of active connections that can be allocated from this pool at the same time, or negative for no limit. -->
    <property name="maxIdle" value="15"/> <!-- The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit. -->
    <property name="minIdle" value="10"/> <!-- The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none. -->
    <property name="timeBetweenEvictionRunsMillis" value="10000"/> <!-- the idle evicter thread evicts idle connections -->
    <property name="minEvictableIdleTimeMillis" value="60000"/> <!-- time a connection may be idle until it can be evicted -->

    <property name="validationQuery" value="/* ping */ SELECT 1"/>
    <property name="testOnBorrow" value="true"/> <!-- test the connection using the ping validationQuery before it is given to the application -->
    <property name="testWhileIdle" value="true"/> <!-- in addition to testOnBorrow, test connections while they are sitting idle -->

    <!-- If you enable "removeAbandoned" then it is possible that a connection is reclaimed by the pool because it is considered to be abandoned. This mechanism is triggered when (getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3) -->
    <property name="removeAbandoned" value="true"/> <!-- Flag to remove abandoned connections if they exceed the removeAbandonedTimout. If set to true a connection is considered abandoned and eligible for removal if it has been idle longer than the removeAbandonedTimeout. Setting this to true can recover db connections from poorly written applications which fail to close a connection. -->
    <property name="removeAbandonedTimeout" value="300"/> <!-- Timeout in seconds before an abandoned connection can be removed. 300 seconds (5 minutes) is the default -->

</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="punit"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="MYSQL"/>
            <!-- <property name="databasePlatform" value="${hibernate.dialect}"/> -->
            <property name="showSql" value="false"/>
            <property name="generateDdl" value="false"/>
            <!--  <property name="hibernate.connection.autocommit" value="false"/> -->
        </bean>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.connection.autocommit" value="false" />
        </map>
    </property>
</bean>

这是我的 persistence.xml 文件:

<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">    
<persistence-unit name="punit"> <!-- transaction-type="JTA" JTA is the defailt --> 
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>           
    </properties>
</persistence-unit>

最佳答案

背景:当您使用自动事务管理时,Spring最终将(通常在您进行第一次数据库访问时)创建一个 session 。这时候就需要在两个数据库之间进行切换。

因此,您需要做的是禁用自动事务管理并将其替换为手动事务管理。查找调用客户端中的代码的位置以及调用 mbean 的位置。使用手动事务管理包装这些内容并创建适当的 session 。

根据您的代码的工作方式,这可能需要大量工作。关键是要确定哪一方需要更多的工作。想象一下,您有 500 个调用 mbean 的地方,但您可以为所有客户端调用安装一个 HTTP 过滤器,因为它使用 HTTP。

因此,您创建一个过滤器,为客户端数据库创建 session 并将其配置到您的 HTTP 堆栈中。对于 mbean,您可以使用 Spring 的自动事务管理,将其配置为连接到从属数据库。

由于当 session 已经存在时,正常的事务管理不会执行任何操作,因此所有代码都将转到正确的数据库。

注意:在这种情况下您无法使用自动缓存。如果这样做,两个数据库中的对象最终都会出现在您的缓存中,并且真正可怕的事情将会开始发生。

关于java - 如何仅将特定数据库用于托管操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20042296/

相关文章:

java - 如何共享使用 ImageView 功能的数组中的图像?

java - 仅在 Mapper 作业上写入值

Scala 或 Spring 的 Spring 替代品?

java - 属性转换器日期字符串

java - 如何使用 JPA/Hibernate 在 Java 中将 int2 数据库字段用作 boolean 值

java - 在 Spring Boot 中使用 JPA 从具有 OneToMany 关系的实体中删除对象

java - 如何使Java中的多边形对象脉动(例如Atari游戏“冒险”中的 chalice )

java - 创建扩展堆栈的 Deck 类

java - 使用 WebSecurityConfigurerAdapter 而不是 WebMvcConfigurerAdapter 添加 HandlerInterceptor

java - Spring 3 通过注释进行任务调度在服务器上同时运行多个实例