Java 应用创建数据访问代理连接失败
检查以下几个要点:
白名单:是否在 ODP 上将应用服务器 IP 加入了白名单,以及在物理数据库上将 ODP 实例 IP 加入了白名单。
MySQL 客户端:如果直接使用命令行方式可以连接 ODP,说明网络和配置都是正确的。
JDBC Driver for MySQL(mysql-connector-java)版本是否为 5.1.x,目前经过 ODP 兼容性完整测试的版本为 5.1.30 和 5.1.40。
如何修改当前 Session 的 OB 执行超时时间
可通过以下方式进行修改:
在执行的 SQL 语句中带上
select /*+query_timeout(100000000000),trx_timeout(100000000000)*/
的 Hint。ODP 会将该 Hint 透传到 OB 去。该 SQL 语句所运行的 Session 的超时时间就会改变。在 ODP 控制台上配置如下参数,更改每条新连接的超时时间。这种修改方法在 OB 侧用
show parameters like "timeout"
是看不到的。但是 ODP 新建的 session 都会带上这些参数。
SQL 执行超时:SocketTimeoutException 错误
原因:该问题一般是由于慢 SQL 导致。
解决方案:
如果 SQL 执行确实需要较长时间,则需要调整应用端和 ODP 的 socketTimeout 参数。
修改应用端 socketTimeout 参数:
修改数据访问代理 socketTimeout 参数:
如果 SQL 执行耗时非预期时间,则需要分析 ODP 的执行耗时日志
logs/zdalproxy/sql-digest.log
,且需要前往物理库进一步分析慢 SQL 原因。
批量更新报错 bad SQL grammar [], Syntax error
现象:使用 MyBatis 对 ODP 进行批量更新,出现 bad SQL grammar [], Syntax error 错误。当前批量更新写法如下:
原因:根据上述的写法,实际上产生的 SQL 语句是 multisql 类型,也就是用分割符 ;
分割开的多条 update 语句。ODP 不支持这种multisql类型的语句,因此会出现语法错误。
解决方案:在实际业务中,批量更新使用多条 update 语句一条一条去更新,不仅性能差而且容易造成阻塞。因此建议通过 case when 编写成一条 SQL 语句来执行,语法示例如下:
UPDATE mytable
SET myfield = CASE id
WHEN 1 THEN 'value'
WHEN 2 THEN 'value'
WHEN 3 THEN 'value'
END
WHERE id IN (1,2,3)
MyBatis 也是完全支持这种写法的,示例如下:
<update id="updateByBatch" parameterType="java.util.List">
UPDATE t_goods
SET NODE_ID = CASE
<foreach collection="list" item="item" index="index">
WHEN GOODS_ID = #{item.goodsId} THEN #{item.nodeId}
</foreach>
END
WHERE GOODS_ID IN
<foreach collection="list" index="index" item="item" open="("separator=","close=")">
#{item.goodsId}
</foreach>
</update>
ODP 是否支持影子表?例如 zdal 的影子表是在表名后加“_t”
ODP 目前不支持自定义后缀。