思路:
通过一个业务单据或者traceId能将整个业务场景所涉及到的单据在同一个页面进行展示
数据表可能是在不同的数据库集群的,因此无法通过数据库原生能力解决该问题,因此需要引入一个"中间商"对业务过程中的数据库操作进行处理,然后进行集中展示。
获取业务过程中数据库变动:
有两个方案
1、通过数据库的binlog进行获取。优点:能够获取到最终的数据,不需要复杂处理。缺点:无法关联业务,只能获取到某个时间段的数据。需要DBA、架构支持
2、通过代码增强,在业务层内获取。优点:能够赋予数据业务场景。不仅仅能够处理MySQL类型数据库。缺点:不是数据库最终数据,处理起来比较麻烦。
同一个时间段内,会有多个需求同时进行测试,某个时间段内会有很多干扰的数据,因此binlog并不太明满足我们的需求,因此选了方案2。
//BEFORE
try{
//RETURN
return;
}catch(Throwable cause){
// THROWS
}
moduleEventWatcher.watch( filter, listener, Event.Type.RETURN, vent.Type.THROW);
传送门:https://github.com/alibaba/jvm-sandbox
com.mysql.cj.jdbc.PreparedStatement#executeInternal
com.mysql.jdbc.PreparedStatement#executeInternal
在module内通过反射调用PreparedStatement#asSql()即可获取SQL语句
传送门:https://github.com/alibaba/transmittable-thread-local
通过对这三种SQL的解析,最终得到以下数据:
如果在执行SQL的时候开启了事务,我们从RETURN事件中获取到的并不是最终提交的数据,因此我们需要感知到事务的提交和回滚。
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
BEGIN 开始一个事务
ROLLBACK 事务回滚
COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
通过对多个数据库框架源码的阅读,大部分采用的都是第二种:开启事务时将AUTOCOMMIT=0,事务结束之后主动调用commit并恢复AUTOCOMMIT=1。
因此我们可以对下面三个地方进行增强:
java.sql.Connection#setAutoCommit
java.sql.Connection#commit
java.sql.Connection#rollback
setAutoCommit(false),增加一个ThreadLocal用来存储SQL。
commit或setAutoCommit(true),标记事务已提交,并发送数据
rollback,标记事务已回滚,并发送数据。
最终呈现示例:
1、兼容更多的数据库:redis、es等
2、提供类似Charles、fiddler类似,实时抓取数据库变更页面
3、根据流量入口进行数据归类