基于mybatis读写分离插件

因此 DataSourceProxy 返回的 Connection是一个代理类, 依赖一个 DataSourceRout 接口,在未执行sql语句之前都是由 Connection代理类完成操作。再执行 sql 语句时,由 DataSourceRout 接口返回具体 Connection执行 sql 语句,DataSourceRout 接口只有一个 getTargetDataSource 方法,由具体实现类根据当前环境确定目标数据源,可能是读写数据源,也可能是分表后的具体目标数据源。

DataSourceRout 接口目前有两个实现类,AbstractRWDataSourceRout 实现读写分离,UserDataSourceRout 实现根据不同的用户路由到不同的数据库组上。UserDataSourceRout 这个类依赖一组 AbstractRWDataSourceRout,实现读写分离。

具体类结构如下:

将 DataSourceProxy 注入到 org.mybatis.spring.SqlSessionTemplate 里面。Mybatis 便实现读写分离。此时对现有代码完全透明。当然也可以注入到 hibernate 框架中,只不过需要自己实现 DataSourceRout 接口,DataSourceRout 接口的实现类AbstractRWDataSourceRout 是基于 mybatis 的。

通过 org.mybatis.spring.SqlSessionTemplate 这个类的源码查询,org.apache.ibatis.mapping.MappedStatement 这个类里面的 org.apache.ibatis.mapping.SqlCommandType 这个域定义了 mybatis 执行 sql 语句类型,可以通过这个类确定当前操作是读操作还是写操作。

写一个 mybatis 的插件,在 sql 执行过程中通 SqlCommandType 这个类确定当前上下文是读操作还是写操作。把读写标记存入上下文中,在 AbstractRWDataSourceRout 这个类中拿取上下文中的读写标记返回对应的数据源,为了事务简单,保证当前上下文最多只有一个写连接和一个读连接,检查当前上下文是否有对应的数据库连接,如果没有相应的连接,获取连接,保存在当前上下文中,方便下次 sql 语句执行和事务执行。

数据源由原来单一数据源变成了一个读数据源和一个写数据源,事务也就变成了两个事务。Mybatis 集成 spring 后,mybatis 的事务交由 spring 管理,具体实现类是 org.mybatis.spring.transaction.SpringManagedTransaction,为了和 myabtis-spring 无缝集成,采用代理模式,RWManagedTransaction 继承 SpringManagedTransaction,把事务分别委托给读写事务,整个线程只有一个读事务和一个写事务,读事务比较弱。因此分布式事务采用 Best Efforts 1PC 模式。

public void commit() throws SQLException {

Map<String, Connection> connectionMap = ConnectionHold.CONNECTION_CONTEXT.get();

Connection writeCon = connectionMap.remove(ConnectionHold.WRITE);

if(writeCon != null){

writeCon.commit();

}

Connection readCon = connectionMap.remove(ConnectionHold.READ);

if(readCon != null){

try {

readCon.commit();

} catch (Exception e) {

e.printStackTrace();

}

}

}

第一个事务成功后,第二个事务有可能因为网络原因或者服务器宕机,不能执行成功,这个网络通讯的危险期虽然概率很小,但是也是个不可靠因素之一。由于整个会话中,只有一个写数据连接和一个读数据连接,读的事务性比较弱,只要写事务成功了,读事务失败影响不大,当然也可以不考虑读事务。因此先处理写事务,再处理读事务。

作为一个初级程序员,想要扩展现有的开源框架,其实不是那么困难,只要实现相应的接口,参考现有实现类实现接口,如果现有的实现类太复杂看不懂逻辑,其实也很好实现接口,就是把自己的实现委托给现有实现类,自己在委托前后做一些自己的业务逻辑。

此插件代码托管在

https://github.com/chenlei2/spring-boot-mybatis-rw

欢迎大家 fork。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值