Mysql主/从复制。[Bug?]内部MySQLConnection对象总是连接到同一主机?

时间:2014-10-24 07:04:51

标签: mysql spring jdbc database-replication mysql-connector

我们使用MySQL主从设置来存储REST API中使用的数据。

我们计划指向主数据库主机或从数据库主机依赖于REST请求参数。

为实现这一目标,我们使用MySQL ReplicationDriver。我们使用MyBatis作为DB和API之间的一层.Spring被用作IOC框架。

我们已经定义了两个方法,它们从DB中检索数据的逻辑相同。 这两种方法之间的区别仅在于,一种方法具有" readOnly = true"在@Transactional注释中,它将指向" slave",另一个具有" readOnly = false"这将指向" master"。

@Override
 @Transactional(value = "itemTrxManager", readOnly = true, rollbackFor = Exception.class)
  public Item getShopItemFromSlave(ItemGetKey itemKey, Options... opts) throws ItemException {
  ..
  }

 @Override
 @Transactional(value = "itemTrxManager", readOnly = false, rollbackFor = Exception.class)
  public Item getShopItemFromMaster(ItemGetKey itemKey, Options... opts) throws ItemException {
  ..
  }

但是我们注意到内部ReplicationDriver(MySQLConnection对象)总是指向它连接的第一个主机,并且在更改" readOnly"之后不会改变。标志。

ie:启动我们的API之后,如果我们发送请求使用" slave" ,ReplicationDriver将使用" slave host"即使我们改为使用" master",它仍然指向" slave host"。 其他方面是相同的:在启动我们的API后,如果我们发送请求使用" master" ,ReplicationDriver将使用" master host"然后如果改为使用" slave",它仍然指向"主控主机"。

请注意,所有日志(Apache DBCP,Spring DAO,MyBatis日志)都显示它连接到正确的主机,但在调试之后我们发现问题出在MySQL驱动程序类中(MySQLConnection对象显示错误的主机名).ie Connection从Apache DBCP DataSource中检索的对象,内部的MySQLConnection对象显示不同的主机信息。

例如,下面显示了我们日志中的一个片段。它说它连接到" slave" ,在调试MySQL Driver内部类时,ReplicationDriver有关于" master"的信息。

  

DEBUG [http-8080-2] [AbstractPlatformTransactionManager.java:365] -   使用名称创建新事务   [com.foo.bar.item.core.businesslogic.impl.MerchantCategoryBusinessLogicImpl.listMerchantCategory]:   PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ' itemTrxManager' DEBUG   [http-8080-2] [DataSourceTransactionManager.java:204] - 获得   连接[jdbc:mysql:// master-host:3301 /,   用户名为=item_user@10.9.203.50,用于JDBC的MySQL Connector Java   transaction DEBUG [http-8080-2] [DataSourceUtils.java:153] - 设置   JDBC连接[jdbc:mysql:// master-host:3301 /,   UserName=item_user@10.9.203.50,MySQL Connector Java]只读

     

DEBUG [http-8080-2] [Slf4jImpl.java:47] - 创建一个新的SqlSession   DEBUG [http-8080-2] [Slf4jImpl.java:47] - 注册交易   SqlSession的同步   [org.apache.ibatis.session.defaults.DefaultSqlSession@329203a8]调查   [http-8080-2] [Slf4jImpl.java:47] - JDBC连接   [jdbc:mysql:// slave-host:3306 /,UserName=item_user@10.9.203.50,MySQL   连接器Java]将由Spring DEBUG [http-8080-2]管理   [Slf4jImpl.java:47] - ooo使用连接   [jdbc:mysql:// slave-host:3306 /,UserName=item_user@10.9.203.50,MySQL   连接器Java] DEBUG [http-8080-2] [Slf4jImpl.java:47] - ==>   准备:选择merchant_category_id,custom_category_id,   merchant_id,parent_id,sibling_position,image_url,create_time,   来自glb_merchant_cat_tbl的update_time,其中merchant_id =?

     

。 。

     

DEBUG [http-8080-2] [Slf4jImpl.java:47] - 事务同步   提交SqlSession   [org.apache.ibatis.session.defaults.DefaultSqlSession@329203a8]调查   [http-8080-2] [Slf4jImpl.java:47] - 事务同步   关闭SqlSession   [org.apache.ibatis.session.defaults.DefaultSqlSession@329203a8]调查   [http-8080-2] [DataSourceUtils.java:222] - 重置只读标志   JDBC连接[jdbc:mysql:// slave-host:3306 /,   UserName=item_user@10.9.203.50,MySQL Connector Java] DEBUG   [http-8080-2] [DataSourceTransactionManager.java:322] - 发布JDBC   连接[jdbc:mysql:// master-host:3301 /,   UserName =item_user@10.9.203.50,MySQL Connector Java]之后   transaction DEBUG [http-8080-2] [DataSourceUtils.java:332] - 返回   JDBC连接到DataSource

如何解决这个问题?这可能是ReplicationDriver中的一个错误?

更新:

这是我们的春天背景:

<!-- this is needed for the annotated transactions to work -->
    <tx:annotation-driven transaction-manager="trx-manager-item" proxy-target-class="true" />

    <bean id="trx-manager-item" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="itemDataSource" />
        <qualifier value="itemTrxManager" />
    </bean>

连接网址:

  

JDBC:MySQL的:复制://主主机:3301,主从:3301 / ITEM2_1 allowMasterDownConnections =真安培; roundRobinLoadBalance =真安培; autoReconnectForPools =真

Context.xml:

<?xml version="1.0" encoding="UTF-8"?>

<Context>



<Resource name="jdbc/item"

auth="Container"

type="javax.sql.DataSource"

factory="com.foo.bar.dbcp.BasicDataSourceFactory"

driverClassName="com.mysql.jdbc.Driver"

defaultAutoCommit="false"

defaultTransactionIsolation="READ_COMMITTED"

removeAbandonedTimeout="600"

timeBetweenEvictionRunsMillis="60000"

minEvictableIdleTimeMillis="60000"

logAbandoned="true"

poolPreparedStatements="true"

removeAbandoned="true"

testOnBorrow="false" 

testOnReturn="false"

validationQuery="select null"

testWhileIdle="true"

/>

连接URL在com.foo.bar.dbcp.BasicDataSourceFactory类中设置。

0 个答案:

没有答案