TOP

MySQL使用ReplicationDriver驱动实现读写分离(一)
2019-09-04 01:00:06 】 浏览:64
Tags:MySQL 使用 ReplicationDriver 驱动 实现 读写 分离

数据库的主从复制环境已经配好,该要解决系统如何实现读写分离功能了。MySQL的jdbc驱动提供了一种实现ReplicationDriver。


1 数据库地址的两种写法


参考:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-url-format.html


因为后续配置可能会用到,先介绍一下mysql url中主机地址的两种写法。


最简单的写法就是 host:port ,如 192.168.5.128:3306,如果端口是缺省的3306,也可以不写,直接使用 192.168.5.128。


更复杂的写法是指定属性,格式为 address=(host=host_or_ip)(port=port)(key1=value1)(key2=value2)...(keyN=valueN),如 address=(host=192.168.5.128)(port=3306)(type=master)。


2 数据池配置


参考:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-master-slave-replication-connection.html


driverClassName: com.mysql.jdbc.ReplicationDriver


url字符串格式:


jdbc:mysql:replication://[master host][:port],[slave host 1][:port][,[slave host 2][:port]]...[/[database]][?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]


数据库地址的写法有两种,上面是第一种简单的写法,ReplicationDriver默认将第一个数据库服务器作为Master库,后续其他数据库服务器作为从数据库。


如果数据库主从设置了多台数据库作为Master,则url格式为:


jdbc:mysql:replication://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/database[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]


3 ReplicationDriver的调用方法


Mysql驱动使用究竟使用 master还是 slave数据库,取决于 Connection.getReadOnly()的值。如果值为false,则将命令发送到master数据库,如果值为true,则将命令发送到slave数据库。当有多台slave数据库时,使用轮询调度(round-robin)算法选择某一台slave数据库。


所以,为了让mysql驱动能够准确的将命令发送到master或slave,代码需要在获取到数据连接后,执行命令 Connection.setReadOnly(true) 或 Connection.setReadOnly(false)。


以下是mysql官方提供的示例代码


import java.sql.ResultSet;


import java.util.Properties;


import com.mysql.jdbc.ReplicationDriver;


public class ReplicationDriverDemo {


  public static void main(String[] args) throws Exception {


    ReplicationDriver driver = new ReplicationDriver();


    Properties props = new Properties();


    // 从库上允许自动重连


    props.put("autoReconnect", "true");


    // 多台从库使用负载均衡


    props.put("roundRobinLoadBalance", "true");


    props.put("user", "foo");


    props.put("password", "password");


    Connection conn = driver.connect("jdbc:mysql:replication://master,slave1,slave2 /test", props);


    // 在主库上读写,设置 read-only 为 "false"


    conn.setReadOnly(false);


    conn.setAutoCommit(false);


    conn.createStatement().executeUpdate("UPDATE some_table ....");


    conn.commit();


    // 现在在从库上执行查询,驱动会自动选择一台从库执行查询


    conn.setReadOnly(true);


    ResultSet rs = conn.createStatement().executeQuery("SELECT a,b FROM alt_table");


    .......


  }


}
 


 


4 Spring TX实现读写分离


项目使用Spring Transaction管理事务,注解Transactional已经帮我们做了封装,注解属性 readOnly,缺省为 false。



/**


 * {@code true} if the transaction is read-only.


 * Defaults to {@code false}.


 * <p>This just serves as a hint for the actual transaction subsystem;


 * it will <i>not necessarily</i> cause failure of write access attempts.


 * A transaction manager which cannot interpret the read-only hint will


 * <i>not</i> throw an exception when asked for a read-on
MySQL使用ReplicationDriver驱动实现读写分离(一) https://www.cppentry.com/bencandy.php?fid=57&id=250035

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Oracle推进SCN系列:使用oradebug.. 下一篇Oracle数据库之单行函数详解