问题描述:
最近在做一个GPS实时监控系统,数据的实时更新是关键。我采用的思路如下:把接收到的源源不断的GPS定位数据往数据库中写,一个数据对(x,y)为一条数据库记录,页面这头不断去读数据库的最近记录,从而显示出车载GPS的运动。
但不知道如何控制读与写的同步,写程序(WinForm程序),暂时启名叫"writer",先打开了数据库在往里写,记录不断增加,读数据库程序(WebForm程序)后打开,但它去读的时候,总是不能读到“writer"启动以后写近去的记录,是不是因为锁的原因?
请教大家,如何实现数据库的同步读写啊?
解析:
你在写数据的时候要看你数据库允许的锁定级别是什么,每种数据库都不一样,如果是最高级别的锁你在写数据的时候其他事务是无法对他进行写 *** 作的,如果是读就会发生 (1)读事务读取的数据不同(2)发生对未提交的更新的依赖。
则读事务在读数据的时候需要申请读锁。建议是你不要通过扫数据库来查找更新,把数据放到内存中通过缓冲区进行交换那样更好
为方便完成指定数据表的同步 *** 作,可以采用dblink与merge结合的方法完成。
*** 作环境: 此数据库服务器ip为192.168.196.76,有center与branch两个库,一般需要将center的表数据同步到branch,center为源库,branch为目标库,具体步骤如下:
1.在源库创建到目标库的dblink
create database link branch --输入所要创建dblink的名称,自定义
connect to dbuser identified by “password” --设置连接远程数据库的用户名和密码
using '192.168.196.76/branch' --指定目标数据库的连接方式,可用tns名称
在创建dblink时,要注意,有时候可能会报用户名和密码错误,但实际上我们所输入的账户信息是正确的,此时就注意将密码的大小写按服务器上所设置的输入,并在账号密码前号加上双引号(服务器版本不同造成的)。
2.成功后验证dblink
select * from tb_bd_action@branch--查询创建好的brach库
正常情况下,如果创建dblink成功,可采用该方式访问到远程数据库的表.
3.通过merge语句完成表数据同步
此例中需要将center库中的tb_sys_sqlscripe表同步到branch,简单的语法如下:
merge into tb_sys_sqlscripe@branch b using tb_sys_sqlscripe c on (b.pk=c.pk) --从center将表merge到branch,同步的依据是两个表的pk
when matched then update set b.sqlscripe=c.sqlscripe,b.author=c.author --如果pk值是相同则将指定表的值更新到目标表
when not matched then --如果pk值不一至,则将源表中的数据整条插入到目标表中
insert values (c.pk, c.fk, c.createtime, c.lastmodifytime,c.author,c.module,c.deleteflag, c.scripttype)
commit --记得merge后必须commit,否则更改未能提交
4.为方便每次需要同步时自动完成同步工作,可将该语句做成存储过程或脚本来定时执行或按要求手动执行,简单说一下创建脚本的方法:
a.创建merge文件夹
b.先将merge语句写完整后,存到merge.sql文件中
c.新建merge.bat文件,编辑后写入以下内容
sqlplus user/password@serverip/database @"%cd%\merge.sql"
前提条件您需要在您RDS for MySQL所在的云账号下开通阿里云数据传输服务。并 点击此处
下载dts-ads-writer插件到您的一台服务器上并解压(需要该服务器可以访问互联网,建议使用阿里云ECS以最大限度保障可用性)。服务器上需要有Java
6或以上的运行环境(JRE/JDK)。
*** 作步骤
1. 在分析型数据库上创建目标表,数据更新类型为实时写入,字段名称和MySQL中的建议均相同;
2. 在阿里云数据传输的控制台上创建数据订阅通道,并记录这个通道的ID;
(见: https://help.aliyun.com/document_detail/dts/Getting-Started/data-subscription.html),
3. 配置dts-ads-writer/app.conf文件,配置方式如下:
所有配置均保存在app.conf中,运行前请保证配置正确;修改配置后,请重启writer
基本配置:
{
"dtsAccessId": "", // 拥有数据订阅通道的云账号的accessId, 必须配置
"dtsAccessKey": "", // 拥有数据订阅通道的云账号的accessKey, 必须配置
"dtsTunnelId": "", // 数据订阅通道的id, 必须配置注意是id,不是通道名称
"adsUserName": "", // 访问您的分析型数据库的用户名(accessId), 必须配置
"adsPassword": "", // 访问您的分析型数据库的密码(accessKey), 必须配置
"adsJdbcUrl": "", // 访问分析型数据库的jdbc连接串, 必须配置(格式jdbc:mysql://ip:port/dbname)
"tables": [
{
"source": {
"primaryKeys": [""] // 主键定义, 必须配置注意RDS和分析型数据库中的主键定义必须一致
"db": "", // 源头RDS的db名称, 必须配置
"table": "",// 源头RDS的table名称, 必须配置
"skipColumns": ["col1"] // 可选,若在此配置了RDS表某列名,则该列不会同步
},
"target": {
"table": "" // 分析型数据库表的table名称, 必须配置
},
"columnMapping": {
"": "" // rds表和ads表的列对应关系:key为rds的列名, value为分析型数据库的列名,选填,不填则按照列名一一对应
}
}
]
}
tables节点的配置示例,
表示rds_db库下的rds_table表对应ads_table表,并且rds_table表的col1列对应ads_table表的col1_ads列,
rds_table表的col2列对应ads_table表的col2_ads列
"tables": [
{
"source": {
"primaryKeys": [
"col1",
"col2"
],
"db": "rds_db",
"table": "rds_table"
},
"target": {
"table": "ads_table"
},
"columnMapping": {
"col1": "col1_ads",
"col2": "col2_ads"
}
}
]
注意事项:
1)RDS for MySQL表和分析型数据库中表的主键定义必须完全一致;如果不一致会出现数据不一致问题。如果需要调整RDS/分析型数据库表的主键,建议先停止writer进程;
2)一个插件进程中分析型数据库db只能是一个,由adsJdbcUrl指定;
3)一个插件进程只能对应一个数据订阅通道;如果更新通道中的订阅对象时,需要重启进程
4)RDS for MySQL中DDL *** 作不做同步处理;
5)更新app.conf需要重启插件进程才能生效;
6)如果工具出现bug或某种其它原因需要重新同步历史数据,只能回溯最近24小时的数据(在阿里云数据传输的控制台中修改消费位点);
7)插件的最大同步性能与运行插件的服务器的互联网带宽和磁盘IOPS成正比。
4. 运行dts-ads-writer/bin/startup.sh(sh bin/startup.sh);
5. 配置监控程序监控进程存活和日志中的常见错误码。
logs目录下的日志中的异常信息均以ErrorCode=XXXX ErrorMessage=XXXX形式给出,可以进行监控
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)