V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Lighfer
V2EX  ›  Java

请教一个代理 JDBC 连接方案的可行性

  •  1
     
  •   Lighfer · 2019-03-06 17:50:39 +08:00 · 2020 次点击
    这是一个创建于 2090 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上头要求要实现一个通用的数据库访问服务,其他业务系统所有的数据库访问都会通过该服务来执行,但是又不希望在开发阶段拆分出来(是的,我也很纳闷为什么非要这样,已经提出过其他方案都被打回了),因此,想到如下的实现方案:

    1. 实现一个执行服务,该服务中维护连接池(HikariCP),及池内 Connection 等的状态
    2. 实现一个 DataSource 模块,代理 Connection、Statement、PreparedStatement、CallableStatement、ResultSet 的所有方法,将调用转发到执行服务,可采用 RPC 的方式,并需要带上一个唯一标识符,假设是 UUID
    3. 执行服务收到调用后,根据 UUID 找到对应的 Connection,如果没有的话就从连接池中获取一个 Connection,并标记该 Connection 处于使用中的状态,不允许被其他调用使用
    4. 业务系统按照正常的方式(JPA)进行开发,但是需要修改数据库连接的数据源,改由 DataSource 模块提供
    5. 对于使用中的 Connection,都要维护其打开的 Statement、PreparedStatement、CallableStatement、ResultSet,直到调用 close,调用 close 后除 Connection 外其他释放资源,将 Connection 归还到连接池

    该方案目前想到的一个问题比较不好处理的问题:ResultSet 有可能是懒加载的,也就意味着一条查询可能会需要多次从执行服务中获取结果集,对于插入和更新同理

    个人觉得该方案理论上是可行的,且不算是特别复杂,但是又担心有哪些隐形的坑,所以想请教各位帮忙分析下,万分感谢!

    1 条回复    2019-03-07 17:05:07 +08:00
    Lighfer
        1
    Lighfer  
    OP
       2019-03-07 17:05:07 +08:00
    虽然没人回我.. 但是还是自己回一个结论吧:该方案不可行,根本原因如下:

    如果要实现数据库访问和业务开发独立,就意味着业务系统对数据的处理(如:映射 ResultSet 为对应的 Java 对象)和最终执行访问数据库的 JDBC 连接不是在一个服务内
    JDBC 执行结果最终是返回 ResultSet,而 ResultSet 在该场景下存在两个问题
    1. ResultSet 不可序列化,意味着远程服务调用没法直接返回
    2. 数据库驱动对 ResultSet 的实现是持有数据库连接的,因为 ResultSet 从数据库中取值不一定是一次性加载,可能会在调用`ResultSet.next`根据需要多次通过 Connection 取值,这意味着远程返回给业务系统的 ResultSet 是不可能持有 Connection 的

    针对问题 1:可以采用对不同的数据库驱动实现的 ResultSet 进行封装,这个还是属于可解决问题
    针对问题 2:只能(在我看来只能)在业务系统上对的 ResultSet 的所有方法代理,转发给远程实际的 ResultSet 执行,但是这会导致两个系统之间的交互非常频繁,大大增加资源消耗和延迟。

    也就是说,由于业务系统不持有数据库连接,如果要实现通用的数据库访问服务,那么就需要保证业务系统每一次调用都能直接获得完整的结果,这就需要对 ResultSet 的处理在数据库访问服务这一侧实现,而这部分逻辑是业务相关的,是在业务系统这一侧实现的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2966 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:43 · PVG 22:43 · LAX 06:43 · JFK 09:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.