如何使用jdbc数据源控制工作程序事务?

时间:2017-04-18 14:59:53

标签: apache-spark jdbc apache-spark-sql

当使用spark删除(或更新)并插入时,要么全部成功,要么都失败。

而且我认为spark应用程序分布在许多JVM上,如何控制每个worker事务同步?

// DELETE: BEGIN
Class.forName("com.oracle.jdbc.Driver");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
String query = "delete from users where id = ?";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt(1, 3);
preparedStmt.execute();
// DELETE: END

val jdbcDF = spark
  .read
  .jdbc("DB_URL", "schema.tablename", connectionProperties)
  .write
  .format("jdbc")
  .option("url", "DB_URL")
  .option("dbtable", "schema.tablename")
  .option("user", "username")
  .option("password", "password")
  .save()

1 个答案:

答案 0 :(得分:2)

tl; dr 你不能。

Spark是a fast and general engine for large-scale data processing(即多线程分布式计算平台),主要卖点是你可能并且肯定会执行多个同时运行的任务来更快地处理大量数据集(甚至可能更便宜)。

JDBC不是非常适合Spark的数据源,因为您受JDBC数据库容量的限制。这就是为什么许多人从JDBC数据库迁移到HDFS或Cassandra或类似的数据存储,成千上万的连接不是一个问题(更不用说在Spark接触数据之前分割数据集等其他好处)。

您可以使用某些configuration parameters来控制JDBC(例如partitionColumnlowerBoundupperBoundnumPartitionsfetchsize,{{1}或者batchsize)给你一些灵活性,但是希望“事务同步”超出了Spark的范围。

直接使用JDBC(就像你对DELETE所做的那样)。

请注意,isolationLevelDELETE: BEGIN之间的代码在驱动程序上执行(在单个线程上)。