在应用层通过spring解决数据库读写分离

本文章转自:如何配置mysql数据库的主从?

单机配置mysql主从:

常见的解决数据库读写分离有两种方案

1、应用层

spring实现数据库读写分离

目前的一些解决方案需要在程序中手动指定数据源,比较麻烦,后边我会通过AOP思想来解决这个问题。

2、中间件

mysql-proxy:

Amoeba forMySQL:和

此处我们介绍一种在应用层的解决方案,通过spring动态数据源和AOP来解决数据库的读写分离。

该方案目前已经在一个互联网项目中使用了,而且可以很好的工作。

该方案目前支持

一读多写;当写时默认读操作到写库、当写时强制读操作到读库。

考虑未来支持

读库负载均衡、读库故障转移等。

使用场景

不想引入中间件,想在应用层解决读写分离,可以考虑这个方案;

建议数据访问层使用jdbc、ibatis,不建议hibernate;

优势

应用层解决,不引入额外中间件;

在应用层支持『当写时默认读操作到写库』,这样如果我们采用这种方案,在写操作后读数据直接从写库拿,不会产生数据复制的延迟问题;

应用层解决读写分离,理论支持任意数据库。

缺点

1、不支持@Transactional注解事务,此方案要求所有读方法必须是read-only=true,因此如果是@Transactional,这样就要求在每一个读方法头上加@Transactional 且readOnly属性=true,相当麻烦。 😳

2、必须按照配置约定进行配置,不够灵活。

两种方案

方案1:当只有读操作的时候,直接操作读库(从库);

当在写事务(即写主库)中读时,也是读主库(即参与到主库操作),这样的优势是可以防止写完后可能读不到刚才写的数据;

此方案其实是使用事务传播行为为:SUPPORTS解决的。

方案2:当只有读操作的时候,直接操作读库(从库);

当在写事务(即写主库)中读时,强制走从库,即先暂停写事务,开启读(读从库),然后恢复写事务。

此方案其实是使用事务传播行为为:NOT_SUPPORTS解决的。

核心组件

cn.javass.common.datasource.ReadWriteDataSource:读写分离的动态数据源,类似于AbstractRoutingDataSource,具体参考javadoc;

cn.javass.common.datasource.ReadWriteDataSourceDecision:读写库选择的决策者,具体参考javadoc;

cn.javass.common.datasource.ReadWriteDataSourceProcessor:此类实现了两个职责(为了减少类的数量将两个功能合并到一起了):读/写动态数据库选择处理器、通过AOP切面实现读/写选择,具体参考javadoc。

具体配置

1、数据源配置

1.1、写库配置

<bean id="writeDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource"><property name="alias" value="writeDataSource"/><property name="driver" value="${write.connection.driver_class}" /><property name="driverUrl" value="${write.connection.url}" /><property name="user" value="${write.connection.username}" /><property name="password" value="${write.connection.password}" /><property name="maximumConnectionCount" value="${write.proxool.maximum.connection.count}"/><property name="minimumConnectionCount" value="${write.proxool.minimum.connection.count}" /><property name="statistics" value="${write.proxool.statistics}" /><property name="simultaneousBuildThrottle" value="${write.proxool.simultaneous.build.throttle}"/></bean>

1.2、读库配置

<bean id="readDataSource1" class="org.logicalcobwebs.proxool.ProxoolDataSource"><property name="alias" value="readDataSource"/><property name="driver" value="${read.connection.driver_class}" /><property name="driverUrl" value="${read.connection.url}" /><property name="user" value="${read.connection.username}" /><property name="password" value="${read.connection.password}" /><property name="maximumConnectionCount" value="${read.proxool.maximum.connection.count}"/><property name="minimumConnectionCount" value="${read.proxool.minimum.connection.count}" /><property name="statistics" value="${read.proxool.statistics}" /><property name="simultaneousBuildThrottle" value="${read.proxool.simultaneous.build.throttle}"/> </bean>

1.3、读写动态库配置

通过writeDataSource指定写库,通过readDataSourceMap指定从库列表,从库列表默认通过顺序轮询来使用读库,具体参考javadoc;

<bean id="readWriteDataSource" class="cn.javass.common.datasource.ReadWriteDataSource"><property name="writeDataSource" ref="writeDataSource"/><property name="readDataSourceMap"><map><entry key="readDataSource1" value-ref="readDataSource1"/><entry key="readDataSource2" value-ref="readDataSource1"/><entry key="readDataSource3" value-ref="readDataSource1"/><entry key="readDataSource4" value-ref="readDataSource1"/></map></property> </bean>

2、XML事务属性配置

你的选择是做或不做,但不做就永远不会有机会

在应用层通过spring解决数据库读写分离

相关文章:

你感兴趣的文章:

标签云: