您的位置:首页 > 编程语言

编程回忆之运维回忆(数据丢失)

2013-12-15 15:28 603 查看
       在项目实施的过程中,经常的会发生数据丢失的事情。如何挽回损失,最好的方式就是做数据备份。
        做数据备份的时候,涉及备份频率,备份数据量。当备份频率和备份数据量上去之后,数据备份的代价其实是比较大的。所以为了防止数据丢 失,还是得从根本上想办法,控制好数据的读写。我这边简单举一个例子。说明数据读写发生的错误。

这个项目使用的ssh架构。有这么一张表。

 

create table "EIS"."XTWH_GGB"(
"GGID" NUMBER not null,
"JSKS" NUMBER,
"FBR" NUMBER,
"JSR" NUMBER,
"BT" VARCHAR2(100) not null,
"NR" CLOB,
"FBSJ" TIMESTAMP(6) not null unique,
"YXSJ" TIMESTAMP(6) default 'NULL' not null,
"ZT" NUMBER,
"SFJJ" NUMBER,
constraint "PK_YY_TBBS" primary key ("GGID")
);

 

这个就是表结构。注意到Nr字段了么。这个字段的类型是CLOB类型。
Nr字段在hibernate当中的映射是这样子的。

       
<property name="nr" type="java.lang.String">
<column name="NR">
<comment>fck</comment>
</column>
</property>


 
          如果使用hibernate读出Nr数据的时候,由于hibernate内部的机制,ClOB自动回转为对应的String。当时如果我们用select * from XTWH_GGB取出数据后,之接使用String.valueOf将Nr转为字符串,我们不会得到想要的数据,只能得到一堆莫名其妙的字符。

       这时候问题就来了。在这个项目里面有一个定时器每天都在读取Nr地段,然后将其重新写入。令人郁闷的是,他都是用sql语句读出数据后,直接String.valueOf掉,然后使用hibernate的数据插入功能,将数据插回表中。这个时候数据发了错误。

        这个bug是比较隐秘的,因为被定时器执行过且重新插入的数据,视为过期数据,是无法再界面上看到的。后面因为系统维护,需要查看到这部分数据。我打开后,Nr字段的数据很多是一堆乱码。
后面经过备份数据库,对比数据后,才发现数据出现了问题。

 
             这个数据丢失发生的关键点在哪里呢,在于CLOB转String的过程中出现了问题。
CLOB如何转为String格式呢,我这边附带一段代码。

//oracle.sql.Clob类型转换成String类型
public String ClobToString(Clob clob) {
String reString = "";
Reader is = null;
try {
is = clob.getCharacterStream();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 得到流
BufferedReader br = new BufferedReader(is);
String s = null;
try {
s = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
StringBuffer sb = new StringBuffer();
while (s != null) {
//执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
sb.append(s);
try {
s = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
reString = sb.toString();
return reString;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: