达梦数据库报“网络通信异常”分析解决

前言:

    达梦数据库在通过程序插入具有BLOB字段的记录时(非通过SQL直接插入),报“通信异常”,通过更换达梦库驱动包解决。

问题:

    在一个项目现场,在进行数据导入时,总时报“网络通信异常”:

19:08:56 ERROR - Application exception overridden by rollback exception
org.springframework.dao.DataAccessResourceFailureException: PreparedStatementCallback; SQL [INSERT INTO SCHEMA1.A(ID,REV,NAME,DEPLOYMENT_ID,BYTES,GENERATED) VALUES (?,?,?,?,?,?)]; 网络通信异常; nested exception is java.sql.SQLException: 网络通信异常
	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:105)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:894)
...

 

分析解决:

1、试验一:参照网上针对“通信异常”的处理,未能解决问题

网上针对“通信异常”的处理,较多的解决方案是在数据源的配置中增加连接探测参数,但经过测试,发现并不管用:

      testOnBorrow: true #是否打开获取连接前探测连接是否可用
      validationQuery: select 1 from dual #测试连接的sql
      testWhileIdle: true

而且该问题能稳定重现,考虑倒是不是网络或数据库的问题,但该机器上同时部署有其他的应用,且都连接的同一数据库,其他应用工作正常。怀疑数据库是不是有什么问题,在一定条件下触发了“通信异常”,决定让现场替换数据库再试。

2、试验二:通过替换数据库,发现问题消除

    将达梦7换为达梦6,问题消除。 说明数据库层面可能存在问题,一个数据库有问题,一个没有问题。于是决定寻找数据库层面的差异,考虑到是插入某个表时报异常,决定重点比较2个库中的同一名称的表是否有不同。

--DM6
CREATE TABLE "A_DB"."SCHEMA1"."A"(
"ID" VARCHAR(64),
"REV" INTEGER,
"NAME" VARCHAR(255),
"DEPLOYMENT_ID" VARCHAR(64),
"BYTES" BLOB(2147483647),
"GENERATED" NUMBER(20,0),
PRIMARY KEY("ID"),
CONSTRAINT "A_DEPL" FOREIGN KEY("DEPLOYMENT_ID") REFERENCES "B"("ID"))
 STORAGE( INITIAL 1 , NEXT 1 , MINEXTENTS 1 , on "PRIMARY", FILLFACTOR 0 ) ;
 
--DM7
CREATE TABLE "SCHEMA1"."A"
(
"ID" VARCHAR2(64),
"REV" INTEGER,
"NAME" VARCHAR2(255),
"DEPLOYMENT_ID" VARCHAR2(64),
"BYTES" BLOB,
"GENERATED" NUMBER,
CONSTRAINT "A_DEPL" FOREIGN KEY("ID") REFERENCES "SCHEMA1"."B"("ID")) STORAGE(ON "SCHEMA1", CLUSTERBTR) ;
COMMENT ON COLUMN "SCHEMA1"."A"."BYTES" IS '字节流';
COMMENT ON COLUMN "SCHEMA1"."A"."DEPLOYMENT_ID" IS '流程部署ID';
COMMENT ON COLUMN "SCHEMA1"."A"."GENERATED" IS '是否引擎生成';
COMMENT ON COLUMN "SCHEMA1"."A"."ID" IS '唯一标识';
COMMENT ON COLUMN "SCHEMA1"."PT_WF_GE_BYTEARRAY"."NAME" IS '名称';
COMMENT ON COLUMN "SCHEMA1"."PT_WF_GE_BYTEARRAY"."REV" IS '版本修订';

通过比较2个表的SQL,发现一个库中的表错误地使用主键ID字段作为外键,与另一表进行关联,那么A表的插入必然依赖于B表,若B表无此ID,则A表插入将因违反约束而失败。

但修改后问题依旧。

3、试验三:使用单独的SQL插入数据库

INSERT INTO SCHEMA1.A(ID,REV,NAME,DEPLOYMENT_ID,BYTES,GENERATED)
VALUES ('TEST001',1,'测试','dep001',0x0000FFFF0A000110,0);

可以成功。

4、试验四:更换数据库驱动包

  将应用包中达梦的数据库驱动包更换为最新版本,问题解决。推测,现有的驱动包可能存在什么缺陷,在处理含BLOB字段记录的插入时可能存在处理不足。有点遗憾的是,因为JDBC包较为复杂,没有足够的时间去找到真正的问题点。

你可能感兴趣的:(JavaApp)