案例-數據源切換讀寫分離

數據庫主備

在高併發的環境下數據庫常常會進行高可用的拓展,例如分庫分表,讀寫分離,集羣,主備,主備複製,當然也會暴露很多的問題:數據遷移,數據一致性,單點故障等等問題。

(當然上述的內容都要根據公司內部的業務場景、數據量、訪問量、併發量、高可用的要求)

這些大部分的操作都不是開發人員操心的,我們操心的是如何在應用層的讀寫分離(驅動層應該會更好吧),多數據源主備切換等等,此次分享的就是一個在Mybaits+spring整合的情況下多數據源切換和讀寫分離的案例

項目說明

1.讀寫分離:寫操作進入到主庫,讀操作進入到備庫集。
2.多數據源:採用一主多從的數據源配置 ,根據操作切換數據源
3.使用java項目搭建

注意:讀寫分離的情況下,主備數據同步依靠於本身提供的數據庫同步複製功能

項目

  1. 加入項目需要的jar包

這裏寫圖片描述

  1. 項目配置文件

這裏寫圖片描述

  1. 項目
    這裏寫圖片描述

2.1 applicationContext.xml (頭尾省去)

<context:annotation-config />
<!-- <context:component-scan base-package="dao" /> -->
<aop:aspectj-autoproxy/>
<!-- ibatis3 工廠類 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:sqlMapConfig.xml" />
    </bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>
<bean id="dynamicSqlSessionTemplate" class="datasource.DynamicSqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
        <constructor-arg index="1" ref="sqlSessionTemplate" />
</bean>
<!-- mapper掃描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionTemplate" ref="dynamicSqlSessionTemplate"></property>
<!-- 掃描包路徑,如果需要掃描多個包,中間使用半角逗號隔開  com.yuhiwy.SysManager.dao-->
        <property name="basePackage" value="dao"></property> 
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

2.2 applicationContext-tx.xml


    <!-- 定義單個jdbc數據源的事務管理器 -->
    <bean id="transactionManager"
        class="datasource.DynamicDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 以 @Transactional 標註來定義事務  -->
    <tx:annotation-driven transaction-manager="transactionManager"/>


    <!-- 配置事務的傳播特性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="delete*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="update*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="proc*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="select*" read-only="true" />
            <tx:method name="*" read-only="false" />
            <!-- <tx:method name="*" read-only="true" /> -->
        </tx:attributes>
    </tx:advice>

    <aop:aspectj-autoproxy/>
    <!-- 那些類的哪些方法參與事務 -->
    <aop:config>
        <aop:pointcut id="allManagerMethod" expression="execution(* dao..*(..))" />
        <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />
    </aop:config>

2.3 application-dataSource.xml

    <!-- C3P0連接池配置 -->
    <bean id="master" class="com.alibaba.druid.pool.DruidDataSource">

         <!-- 基本屬性 url、user、password -->  
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/db1"/>  
        <property name="username" value="root"/>  
        <property name="password" value="root"/>  

        <!-- 配置初始化大小、最小、最大 -->  
        <property name="initialSize" value="20"/>  
        <property name="minIdle" value="20"/>  
        <property name="maxActive" value="200"/>  

        <!-- 配置獲取連接等待超時的時間 -->  
        <property name="maxWait" value="255000"/>  

    </bean>

    <bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource">
     <!-- 基本屬性 url、user、password -->  
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/db2"/>  
        <property name="username" value="root"/>  
        <property name="password" value="root"/>  

        <!-- 配置初始化大小、最小、最大 -->  
        <property name="initialSize" value="20"/>  
        <property name="minIdle" value="20"/>  
        <property name="maxActive" value="200"/>  

        <!-- 配置獲取連接等待超時的時間 -->  
        <property name="maxWait" value="255000"/>  
    </bean>

    <!-- <bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>jdbc:mysql://192.168.1.246:3306/db3</value>
        </property>
        <property name="user">
            <value>ysb</value>
        </property>
        <property name="password">
            <value>ysb</value>
        </property>
        <property name="initialPoolSize">
            <value>20</value>
        </property>
        <property name="minPoolSize">
            <value>20</value>
        </property>
        <property name="maxPoolSize">
            <value>200</value>
        </property>
        <property name="maxIdleTime">
            <value>255000</value>
        </property>
    </bean> -->

    <bean id="dataSource" class="datasource.DynamicDataSource">
        <property name="master" ref="master" />     
        <property name="slaves">
            <list>
                <ref bean="dataSource2"/>
                <!-- <ref bean="dataSource3"/> -->
            </list>         
        </property>
    </bean>

未完待續。

發佈了48 篇原創文章 · 獲贊 8 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章