如何使Spark JDBC驱动程序显示完整的异常?

时间:2017-04-05 02:51:29

标签: apache-spark jdbc

我想从Spark JDBC驱动程序中获取适当的异常消息。

我的测试用例:

  • 使用Spark ver2.0.2通过JDBC驱动程序访问数据库

  • 首先锁定DB,然后尝试写入DB(写入模式是追加并覆盖)

  • 获取异常消息

我收到的异常消息:

  • case1追加:Cause already initialized< -Not good

  • case2 overwrite:DB2 SQL Error: SQLCODE=-913, SQLSTATE=57033, SQLERRMC=00C9008E;00000210;DSN00009.DRITEMRI.00000001, DRIVER=4.19.56< -Good

我的问题:

  • 如何在' case1追加'中找到DB2 SQL Error: SQLCODE=-913, SQLSTATE=57033~等异常消息?

  • 我认为原因是函数 savePartitions(当Spark执行saveTable)没有显示异常时调用此函数。但我不知道如何解决它。

以下是Spark shell的详细异常消息

case1追加:

scala> prodtbl.write.mode("Append").jdbc(url3,"DB2.D_ITEM_INFO",prop1)
17/04/03 17:50:26 ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1)

java.lang.IllegalStateException: Cause already initialized

at java.lang.Throwable.setCause(Throwable.java:365)
at java.lang.Throwable.initCause(Throwable.java:341)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$.savePartition(JdbcUtils.scala:241)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$saveTable$1.apply(JdbcUtils.scala:300)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$saveTable$1.apply(JdbcUtils.scala:299)
at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$28.apply(RDD.scala:902)
at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$28.apply(RDD.scala:902)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1899)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1899)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:70)
at org.apache.spark.scheduler.Task.run(Task.scala:86)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:785)

case2 overwrite:

scala> prodtbl.write.mode("Overwrite").jdbc(url3,"DB2.D_ITEM_INFO",prop1)

com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-913,  SQLSTATE=57033, SQLERRMC=00C9008E;00000210;DSN00009.DRITEMRI.00000001, DRIVER=4.19.56

at com.ibm.db2.jcc.am.kd.a(Unknown Source)
at com.ibm.db2.jcc.am.kd.a(Unknown Source)
at com.ibm.db2.jcc.am.kd.a(Unknown Source)
at com.ibm.db2.jcc.am.fp.c(Unknown Source)
at com.ibm.db2.jcc.am.fp.d(Unknown Source)
at com.ibm.db2.jcc.am.fp.b(Unknown Source)
at com.ibm.db2.jcc.t4.bb.i(Unknown Source)
at com.ibm.db2.jcc.t4.bb.c(Unknown Source)
at com.ibm.db2.jcc.t4.p.b(Unknown Source)
at com.ibm.db2.jcc.t4.vb.h(Unknown Source)
at com.ibm.db2.jcc.am.fp.jb(Unknown Source)
at com.ibm.db2.jcc.am.fp.a(Unknown Source)
at com.ibm.db2.jcc.am.fp.c(Unknown Source)
at com.ibm.db2.jcc.am.fp.executeUpdate(Unknown Source)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$.dropTable(JdbcUtils.scala:94)
at org.apache.spark.sql.DataFrameWriter.jdbc(DataFrameWriter.scala:422)
... 48 elided

1 个答案:

答案 0 :(得分:1)

所以initCause如下所述:

public Throwable initCause(Throwable cause)

将此throwable的原因初始化为指定值。 (原因是导致抛出此抛掷物的抛掷物。) 此方法最多可以调用一次。它通常在构造函数内调用,或者在创建throwable之后立即调用。如果此throwable是使用Throwable(Throwable)Throwable(String,Throwable)创建的,则此方法甚至无法调用一次。

在旧的throwable类型上使用此方法而没有其他支持来设置原因的示例是:

try {
     lowLevelOp();
 } catch (LowLevelException le) {
     throw (HighLevelException)
           new HighLevelException().initCause(le); // Legacy constructor
 }

<强>参数:

原因 - 原因(保存以供以后通过getCause()方法检索)。 (允许空值,表示原因不存在或未知。)

<强>返回:

对此Throwable实例的引用。

<强>抛出:

IllegalArgumentException - 如果原因是这个可抛出的。 (抛弃不可能是它自己的原因。) IllegalStateException - 如果此throwable是使用Throwable(Throwable)或Throwable(String,Throwable)创建的,或者此方法已在此throwable上调用。

这意味着原因不是用initCase方法初始化而你没有收到你等待的东西。