精华内容
下载资源
问答
  • 数据库表同步的三种方法

    千次阅读 2021-01-19 10:01:52
    我刚开始,写了一个程序,多线程去生成数据库(接口有记录,记录请求报文)取到请求报文,然后再拼接成curl请求命令,请求到并行环境,结果跑了没半天就差点儿把生产数据库搞挂。原因是,我的程序每五分钟调用一次...

    1、前言:

    最近项目准备上线,要先做一下并行,所以要把调用接口的请求 请求到生产环境的同时也请求到并行环境。我刚开始,写了一个程序,多线程去生产数据库(接口有记录表,记录请求报文)取到请求报文,然后再拼接成curl请求命令,请求到并行环境,结果跑了没半天就差点儿把生产数据库搞挂。原因是,我的程序每五分钟调用一次,调用会获取11个数据库连接,结果因为生产上数据量大,五分钟没有处理完成,另一个调度就调起来了,这样一下午累积下来,产生了上百个连接,生成cpu飙到了%90以上,触发了告警,领导收到了告警短信才发现了问题。
    之后应领导要求,我的并行程序不能直接连接生产库,需要异步处理(需要数据库做中转),那么就涉及到一个如何获取生产数据库中的报文数据的问题。通过上网查询,大体有三个方案:

    1.1 使用触发器

    在接口报文记录表上添加一个触发器,每次请求的报文插入生产记录表的同时触发器插入到中转数据库。
    优点:编程简单,只需要几行
    缺点:会影响生产数据库性能,同时该触发器需要配合dblink,可能存在潜在危险。

    -- 一个简单的oracle触发器
    CREATE OR REPLACE TRIGGER MY_TGR
    BEFORE INSERT ON jd.ims_json_soap_1_0
    FOR EACH ROW--对表的每一行触发器执行一次,插入test_b的同时插入test_a
    BEGIN
    insert into cd.ims_json_soap_1_0(name,age,school,home,ext)  values(:NEW.name,:NEW.age,:NEW.school,:NEW.home,:NEW.ext);
    END;
    
    1.2 使用canal

    canal是阿里巴巴提供的一个开源工具,通过监听数据库binlog日志,解析出语句,然后执行,该程序对于mysql很友好,但是oracle(归档日志)貌似支持部分.太新的版本应该还不支持,这个还没有尝试。

    1.3 使用kettle

    kettle是一款国外的开源ETL工具,使用的时候只需要下载解压就可以使用,数据抽取速度可以达到每秒上万条数据的同步。

    2、kettle的使用

    2.1 下载安装kettle

    我这里使用的是pdi-ce-7.1.0.0-12
    在这里插入图片描述

    2.2 表同步生成ktr文件

    因为生产数据是实时有调用记录插入的,所以我的同步方案是增量同步。
    通过目标表的最新时间到生产源表里面获取最新的记录

    2.2.1 最终转换效果

    在这里插入图片描述

    2.2.2 MaxDate

    获取目标表(中转数据库中的表)最大时间做为一个表输入。
    在这里插入图片描述

    2.2.3 常规(生产数据库)

    注意下面的从步骤插入数据,sql语句中的问号会在执行的时候替换为下面的MaxData(该名字需要和上一步中的步骤名称保持一致)
    在这里插入图片描述

    2.2.4 表输出

    这里其实还可以使用 插入/更新 但是这种方式相对慢一些,但是更灵活,可以自定义同步的字段,由于我这里表结构都是相同的,所以我采用表输出的方式,这样的效率更高。

    在这里插入图片描述

    在这里插入图片描述
    最后按住shirt通过拖拉将两个输入和一个输出连接起来就可以了
    在这里插入图片描述
    我这里应为分表的关系有十张分表都需要同步,所以我复制了十个这样的转换。

    2.3 执行ktr文件

    在这里插入图片描述
    转换过程
    在这里插入图片描述

    3、java整合kettle,通过程序调用执行ktr文件

    由于我的需要放在服务器上去定时调度,所以我采用的是Java + crontab的方式实现的定时调度执行ktr文件。

       /**
         * 执行ktr文件
         * @param args
         */
        public static void main(String[] args) throws KettleException {
            //初始化ketlle
            KettleEnvironment.init();
            //创建转换元数据对象
            //TransMeta meta = new TransMeta("etl/update_insert_Trans.ktr");
            TransMeta meta = new TransMeta("D:\\Tools\\Kettle\\save\\常规到紧急0分表.ktr");
            Trans trans = new Trans(meta);
            trans.prepareExecution(null);
            trans.startThreads();
            // 等待执行完成
            trans.waitUntilFinished();
            if(trans.getErrors()!=0){
                System.out.println("执行失败!");
            }
        }
    
    展开全文
  • javaoracle如何实现数据库同步?...现在的问题是,当A库中中的数据发生变化(增加、修改、删除数据),B库中对应的数据也会发生变化,也就是数据同步,请问这将如何实现?哪位大神知道的给小弟...

    javaoracle如何实现数据库同步?

    javaweb开发,使用oracle数据库。目前开发一个系统,现在准备两个数据库,其中一个库中(称为A库),的每张表都会初始化一些数据,另一个数据库(称为B库)中有A库的所有表,同时还新建了几张自己特有的表。现在的问题是,当A库中表中的数据发生变化(增加、修改、删除数据),B库中对应的表数据也会发生变化,也就是数据同步,请问这将如何实现?

    哪位大神知道的给小弟讲解下,不胜感激!

    分享到:

    ------解决方案--------------------

    查查关于主从库的相关知识应该能帮到你吧!

    ------解决方案--------------------

    方法很多啊

    数据库自己就能办这事

    如果要手动去做这事的话,你可以写一个方法或过程用JOB读另一个表中的数据

    [java同步数据库表]javaoracle怎么实现数据库同步

    标签:数据库同步   系统   javaweb   手动   自己   同步数据   表数   讲解   oracle

    本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

    本文系统来源:https://www.cnblogs.com/sqlserver-mysql/p/12724658.html

    展开全文
  • 一、事务方法同步问题 例如以下这段代码 @RequestMapping("/test") @Transactional public int test(){ Test test = testMapper.selectById(1); int max = test.getMax() + 1; test.setMax(max); ...

    一、事务方法的同步问题

    例如以下这段代码

        @RequestMapping("/test")
        @Transactional
        public int test(){
            Test test = testMapper.selectById(1);
            int max = test.getMax() + 1;
            test.setMax(max);
            testMapper.updateById(test);
            return max;
        }

    当用jmeter并发访问1000次这个接口,发现max的值为532,跟预期的1000不一样。

    这是因为有些请求查询不到数据库最新的值,导致的同步问题。

     

    这里我使用的项目是springboot+mybatisplus+mysql

     

     

    二、解决方法

    1.使用select for update解决

         @Select("select * from test where id = #{id} for update")
         Test selectForUpdate(@Param("id") long id);

    for update是一种行级锁,又叫排它锁,一旦用户对某个行施加了行级加锁,则该用户可以查询也可以更新被加锁的数据行,其它用户只能查询但不能更新被加锁的数据行.如果其它用户想更新该表中的数据行,则也必须对该表施加行级锁.即使多个用户对一个表均使用了共享更新,但也不允许两个事务同时对一个表进行更新,真正对表进行更新时,是以独占方式锁表,一直到提交或复原该事务为止。行锁永远是独占方式锁。

    只有当出现如下之一的条件,才会释放共享更新锁:
    1、执行提交(COMMIT)语句
    2、退出数据库(LOG OFF)
    3、程序停止运行

     

     

    2.使用手动事务+同步锁synchronized

        @Autowired
        private PlatformTransactionManager platformTransactionManager;
    
        @Autowired
        private TransactionDefinition transactionDefinition;
    
    
        @RequestMapping("/test")
        public synchronized int test(){
            int max = 0;
            TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
            try{
                Test test = testMapper.selectById(1);
                max = test.getMax() + 1;
                test.setMax(max);
                testMapper.updateById(test);
                platformTransactionManager.commit(transactionStatus);
            }catch (Exception e){
                platformTransactionManager.rollback(transactionStatus);
            }
            return max;
        }

    这里使用手动事务的原因是,spring aop中,在方法执行前开启事务,方法执行后提交事务,也就是说事务的开启和提交过程是没有加锁的,因此无法实现同步。

     

     

    以下方式是无法实现同步的:

        @RequestMapping("/test")
        @Transactional
        public synchronized int test(){
            Test test = testMapper.selectById(1);
            int max = test.getMax() + 1;
            test.setMax(max);
            testMapper.updateById(test);
            return max;
        }

    将数据库值清0,再次使用jmeter测试,发现max的值为647。

    说明依然没有解决同步问题。

     

    就算把synchronized放到方法体里也是一样无法实现同步的,锁住的只是方法里的代码块,没有锁住事务的开启和提交过程。

        private Object object = new Object();
        
        @RequestMapping("/test")
        @Transactional
        public int test(){
            int max = 0;
            synchronized (object) {
                Test test = testMapper.selectById(1);
                max = test.getMax() + 1;
                test.setMax(max);
                testMapper.updateById(test);
            }
            return max;
        }

     

     

     

    3.使用乐观锁

    数据库添加version字段。

    public class Test {
        private Long id;
        private Integer max;
        @Version
        private Integer version;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Integer getMax() {
            return max;
        }
    
        public void setMax(Integer max) {
            this.max = max;
        }
    
        public Integer getVersion() {
            return version;
        }
    
        public void setVersion(Integer version) {
            this.version = version;
        }
    }

     

        @RequestMapping("/test")
        @Transactional(isolation = Isolation.READ_COMMITTED)
        public int test(){
            int i = 0;
            Test test = null;
            while(i<1){
                test = testMapper.selectById(1);
                test.setMax(test.getMax()+1);
                i = testMapper.updateById(test);
            }
    
            System.out.println(test.getMax());
            return test.getMax();
        }

    这里因为使用了mybatisplus框架,只需要在bean类version属性添加@Version注释,然后使用框架提供的方法查询和修改,默认支持乐观锁。

    需要注意的是,这里@Transactional注释中标明了隔离级别为读取已提交。

    否则会导致在事务中查询不到数据库最新的数据,导致一直无法更新成功,一直回旋。

    原因是@Transactional默认的隔离级别是根据数据库的隔离级别,由于我用的是mysql的innodb引擎,默认的隔离级别是支持可重复读的,导致在事务中,查询数据库的值都是一致的可重复读的,导致无法获取数据库最新的值。

    因此将事务隔离级别改为读取已提交就可以解决

     

     

    三、总结

    事务方法的同步可以使用以下方法解决:

    select for update

    手动事务+同步锁synchronized(可将锁细化)

    ③乐观锁

     

    并发量不是特别高的话,使用乐观锁的效率最高。

    展开全文
  • 这是用来实现两个 MySQL 数据库中的具有相同字段的增量同步。支持按照某种格式增量获取中的待同步数据。支持按照列名称向 数据库 的中批量插入待同步的数据。安装go get -u github.com/cuckoopark/dbsync...

    这是用来实现两个 MySQL 数据库中的具有相同字段表的增量同步。

    支持按照某种格式增量获取表中的待同步数据。

    支持按照列名称向 数据库 的表中批量插入待同步的数据。

    安装

    go get -u github.com/cuckoopark/dbsync

    数据库配置

    在每一张需要同步的表中,应该有一个update_time

    更新时间的非空字段(名字可以不一样,但是类型必须是时间相关类型),用来按照更新时间获取最新的更新数据。

    这个字段需要在数据更新时,自动更新为当前时间戳,用于记录数据更新的时间。

    例如update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

    的字段设置。

    获取增量更新数据

    可以批量获取一张表的最新更新的数据,方法如下:

    func DoFetch(db *sql.DB, tableName string, options FetchOptions) (FetchResult, error)

    其中参数说明:

    db

    :数据库操作句柄。

    tableName

    :表名称。

    options

    :获取时的配置信息,FetchOptions

    格式如下所示:IgnoreFields

    :需要忽略的列名称,获取数据的结果不包含该列。

    PageNumber

    :分页获取增量的页码,从1开始。

    PageSize

    :分页获取增量的页大小,判断分页是否结束,只需要判断获取结果的数量是否小于页大小即可。

    UpdateTimeFieldName

    :更新时间(即上面说明的update_time

    )所在列的列名称。

    LastUpdateTime

    :上次更新的时间戳,大于这个时间戳开始查询,如果为0,则表示查询全部数据。

    WhereSqlStmt

    :自定义SQL查询语句的Where子句,与更新时间的条件([UpdateTimeFieldName] > ?

    )是AND

    的关系。

    WhereSqlArgs

    :自定义SQL查询语句的Where子句的参数列表。

    获取的结果,是FetchResult

    格式的结构体:

    columns

    column_types

    data

    注:时间类型的列,获取的结果time.Time

    会被转换为时间戳传递,用于节省数据长度。

    插入单条更新数据

    接口为:

    func DoUpdateOne(db executor, tableName string, data []interface{}, options UpdateOptions) error

    其中参数说明:

    db

    :数据库操作句柄。

    tableName

    :表名称。

    data

    :一条数据,里面的值与options.Columns

    一一对应。

    options

    :插入时的配置信息,UpdateOptions

    格式如下所示:Columns

    :列名称列表,参照DoFetch

    返回的结果。

    ColumnTypes

    :列的数据类型列表,参照DoFetch

    返回的结果。

    FixedFields

    :固定的插入列,因为在DoFetch

    中会配置忽略一些列,所以这里可以给这些列设置值。

    UniqueFields

    :唯一键或主键的列名称列表,在插入失败时,更新操作不更新唯一键或主键。

    该接口无返回值。

    插入或更新会调用INSERT INTO ... VALUES (...) ON DUPLICATE KEY UPDATE ...

    这种SQL语句来执行,不采用REPLACE INTO

    的原因是它的更新会先删除旧数据,再插入新数据,可能导致一些忽略的字段被修改。

    批量插入更新数据

    接口为:

    func DoUpdate(db *sql.DB, tableName string, data [][]interface{}, options UpdateMultiOptions) error

    相比较插入单条更新数据的接口,只是数据变成了二维数组,options

    里面多了一个配置项:

    BatchCount

    :一次批量插入的条数,用于加快插入或更新的执行速度。

    展开全文
  • 使用同步监视器的方式有两种:同步代码块以及同步方法。 1.同步代码块 同步代码块的语法格式如下: sychronized(同步监视器对象){ //不能在括号中直接new对象,new了就没效果了 需要被同步的代码块 } 同步代码...
  • 如何正确设置MySQL同步?今天给大家系统介绍mysql同步的设置,在实际的应用中体会设置mysql同步的操作。我们今天主要向大家描述的是正确设置MySQL同步(replication)的实际操作步骤,下面就是文章的主要内容的描述。...
  • 生产环境中mysql主从库同步停止了,不能停服务,在重新开启同步的时候报了错误Could not execute Update_rows event on table [db_name].[table_name];Can't find record in 'qrtz_fired_triggers', Error_code: ...
  • mysql从2个数据库中同步两个

    千次阅读 2021-02-01 19:50:50
    我无法相信你没有找到合适的脚本来做到这一点.根据服务器到服务器的带宽和连接以及数据大小,您可以:>直接转移整个:mysqldump [options] sourcedatabase ...使用MySQL压缩传输# same as above, mys...
  • --binlog-do-db 二进制日志记录的数据库(多数据库用逗号,隔开)--binlog-ignore-db 二进制日志中忽略数据库 (多数据库用逗号,隔开)以下是mysql主从忽略授权方法案例:in master:binlog-do-db=YYY 需要同步的...
  • java 对两张进行数据同步

    千次阅读 2021-01-06 17:39:53
    java对sqlserver两张进行同步操作 功能描述 在大型项目中,我们经常会用到读写分离技术来进行优化,及一张主仅用来查询。一张附表用来增删改。我们现在要做的功能就是当附表数据变动后,要同步更新主。这里...
  • Oracle双向同步问题

    2021-05-03 01:33:41
    开发同学说有一个需求,需要在两个库之间同步一张的数据涉及到两个业务系统,这张表的内容用于页面展示暂且称为A库和B库,表名都相同,称为T该只是新增,思考了下,有两个比较方便的方法:1.定时将A库的T同步...
  • MySQL的主从数据库没有同步?别慌,这篇文章帮你搞定!!
  • vue中的watch方法 实时同步存储数据

    千次阅读 2020-12-29 00:06:26
    RFID基础知识BS:BinarySearch. TSA:TimeSlottedAloha.... FSA:Frame Slo ...WampServer修改MySQL密码WampServer安装后密码是空的,需要设置一下 一般有两种方式: 一是通过phpMyAdmin直接修改: 二是使用WAMP的MySql...
  • 做开发的时候要做MySQL的数据库同步,两台安装一样的系统,都是FreeBSD5.4,安装了Apache 2.0.55和PHP 4.4.0,MySQL的版本是4.1.15,都是目前最新的版本。1、安装配置两台服务器,分别安装好MySQL,都安装在 /usr/...
  • 话题:数据库同步为什么不建议使用dblink方式回答:其实 dblink同步的情况非常常见。但是在Oracle的一些版本(如11.2.0.3)中有一个特别大的隐患。可能会导致scn增长过快,无法同步,并且该症状会通过dblink传染到与之...
  • ORACLE 数据全量/增量同步 merge into 方法一、业务介绍二、创建三、准备数据四、merge into语法使用介绍1.主要综合学习了其他大佬的内容2.如果想全部插入3.删除数据 一、业务介绍 有old和new两张,new是每天...
  • IO_Running: YesSlave_SQL_Running: No可见是Slave不同步下面介绍两种解决方法方法一:忽略错误后,继续同步方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况解决:stop...
  • 1、教程初衷,最近想要使用kettle实现单增量同步,在各种搜索中,在gzh java大师找到视频教程,实现成功后,很是感激,也想通过教程复述的方式记录方法的实现过程、理清思路,好了好了,废话多多少少有点多了。...
  • ①canal.adapter-1.1.5 支持一对一单的增量数据同步ElasticSearch 7; ②对于多聚合场景的SQL满足不了我们的业务需求。 ③采用java canal 接入,可以实现灵活化增量数据准实时同步 文章目录一、java canal 接入...
  • 【图文】表盘、插件、应用及数据面板(DataFields)的使用方法。Garmin可安装的程序类型包括以下四种:表盘(Watch Faces)插件(Widgets)应用程序(APP)数据字段(Data Fields)其中插件和应用程序安装之后在相应的功能区里...
  • 关于不同间的数据同步 工作中遇到一个问题,添加新的数据同步逻辑后,需要对旧数据进行修复,于是需要进行间的数据同步,记录一下 由于同步的目标是一个辅助,其中的数据相较于源数据会少很多,于是得分两...
  • 前言在开发当中我们常常会遇到多线程安全的问题,java中给我们提供了一个同步锁的关键字synchronized,它很好的解决多线程安全问题,本章节主要讲解synchronized用法和写法,避免和多同学在用不知道该如何书写,如有...
  • 异步转同步的解决方案一、前言二、 promise的概念三、promise的使用四、一个因为异步请求出问题的案例五、案例的解决方案1、运用promise解决异步转同步问题2、运用async+await+promise解决异步转同步问题为什么有...
  • 原标题:基于 DataX 数据库基础数据同步 万标2015年加入去哪儿技术团队。目前在金融事业部/支付中心,测试工程师岗位,对技术有浓厚兴趣。一、 问题及背景在此之前,新增的基础数据在上线后,是通过手工在各测试...
  • 本文讨论的内容有以下几个方面:掌握永磁同步电机的成熟控制方法和开发内容后如何转型。永磁同步电机初始角设置的问题。永磁同步电机控制的建模问题讨论,如模型仿真慢、联合仿真问题、PI控制问题等。无位置传感器...
  • 接着上文 配置完Mysql 主从之后,在使用中可能会出现主从同步失败的情况。mysql>show slave status\GSlave_IO_Running: YesSlave_SQL_Running: No可见是Slave不同步。下面介绍两种解决方法方法一:忽略错误后,...
  • 在LAMP架构中,我们一般使用MySQL作为数据库,而MySQL主从也是MySQL主从复制一般情况下我们会设置需要同步的数据库,使用参数配置选项,binlog-do-db,可以在master上指定需要同步的数据库,replicate-do-db在从数据...
  • 前言本文介绍了使用Kettle对一张业务数据(500万条数据以上)进行实时(10秒)同步,采用了时间戳增量回滚同步方法。关于ETL和Kettle的入门知识大家可以阅读相关的blog和文档学习。1. 时间戳增量回滚同步假定在源...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 504,982
精华内容 201,992
关键字:

同步表使用方法