java吧 关注:1,189,553贴子:12,600,877

使用mybatis拦截器拦截并保存增删改的sql记录,但是事务怎么弄

只看楼主收藏回复

最近遇到一个功能,要求用mybatis拦截器拦截用户增删改时操作的的sql记录并存到一张sql日志表里去,拦截和保存的部分都弄出来了,但是遇到一个问题,就是如果拦截的sql操作本身报错然后回滚了,我怎么让保存sql的操作也跟着回滚呢?我目前是在mybatis拦截器的intercept()方法里通过getBean的方法拿到保存sql的dao然后将获取到的sql进行dao.save()的保存操作,但是这样相当于保存sql的操作其实还在sql真正执行之前,如果sql执行报错了,sql日志其实还是保存了,有没有大佬有好的解决方案啊,求助


IP属地:湖北1楼2023-06-26 00:23回复


    IP属地:湖北来自Android客户端2楼2023-06-26 00:26
    回复
      老哥别卷了


      IP属地:广东来自Android客户端3楼2023-06-26 00:32
      回复
        保存SQL有啥意义?看SQL去找Binlog日志


        IP属地:江苏来自Android客户端5楼2023-06-26 02:25
        收起回复
          Transaction声明式事务设置为new标记在service层的方法上,在你的mybatis拦截器中拿到sql后调用这个service的标记方法去插入数据库,这样的话这个事务就跟你sql的执行事务没啥关系了,但是要注意如果你记录sql的事务如果报错的话执行sql也会回滚


          IP属地:河南来自Android客户端6楼2023-06-26 07:03
          回复
            执行完sql后再保存日志,我猜的


            IP属地:广东来自Android客户端7楼2023-06-26 07:59
            回复
              如果是spring 事物的话可以拓展TransactionManager,参考SpringCloudSleuth对tx 的拓展


              IP属地:湖北来自iPhone客户端9楼2023-06-26 08:36
              回复
                可以在拦截时再进行异常拦截处理并手动回滚日志操作


                IP属地:广东来自Android客户端10楼2023-06-26 08:37
                回复
                  报错了就异常处理里面把日志删了,感觉是有可行性的


                  IP属地:重庆来自Android客户端11楼2023-06-26 08:57
                  收起回复
                    插入错误就删除错误记录,更新错误直接改回原数据


                    IP属地:江苏来自Android客户端12楼2023-06-26 09:28
                    回复
                      首先这个功能有弊端,只能是mybatis,换框架不适应。
                      实现:
                      1.用aop做切面,被@Transactional修饰的方法做环绕通知,然后获取异常sql并解析处理。
                      2.如果是用spring或者其他框架做事物得特殊处理。
                      3.可以获取binlog日志(如果只是操作日志)
                      ps 如果只是操作日志,那么失败回滚的按道理不算。如果非要去除报错回滚,可以看看项目用到什么管理事物)spring mybatis jdbc 等),


                      IP属地:湖北来自Android客户端13楼2023-06-26 09:50
                      收起回复
                        有个笨蛋招,你不是不知道哪条是哪条吗。那就拦截每条sql给个uuid。然后事物无论commit还是rollback你就把对应uuid的打印或者删除就好。


                        IP属地:上海来自iPhone客户端14楼2023-06-26 10:55
                        回复
                          可以先把sql拿出来,根据sql执行结果状态做异步写入,不知道这样子行不行,拦截器不会影响事务回滚的,只是你这里是插入了一条执行失败的sql到你们表里面而已,如果是为了查询可以参考一下elk日志搜索,比插入表要好很多


                          IP属地:江西来自Android客户端15楼2023-06-26 11:00
                          回复
                            我有一计,你保存完sql后可以返回生成的id主键吧,把id放threadlocal里面,后续出现异常的时候进入异常处理handler的时候取出id,然后删除


                            IP属地:湖南来自Android客户端16楼2023-06-26 11:09
                            收起回复
                              通过spring的event,保存方法写在event事件处理里面。注解写成translationevent,mybatis拦截器里push保存的event。该注解如果有事物会在事物提交后执行,如果没有会正常流程执行。可完美解决你的需求。


                              IP属地:北京来自iPhone客户端17楼2023-06-26 11:38
                              回复