Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import java.sql.{Connection, PreparedStatement}
import java.util.Properties

import scala.util.Try
import scala.util.control.NonFatal

import org.apache.spark.Logging
import org.apache.spark.sql.jdbc.{JdbcDialect, JdbcType, JdbcDialects}
Expand Down Expand Up @@ -125,8 +126,19 @@ object JdbcUtils extends Logging {
dialect: JdbcDialect): Iterator[Byte] = {
val conn = getConnection()
var committed = false
val supportsTransactions = try {
conn.getMetaData().supportsDataManipulationTransactionsOnly() ||
conn.getMetaData().supportsDataDefinitionAndDataManipulationTransactions()
} catch {
case NonFatal(e) =>
logWarning("Exception while detecting transaction support", e)
true
}

try {
conn.setAutoCommit(false) // Everything in the same db transaction.
if (supportsTransactions) {
conn.setAutoCommit(false) // Everything in the same db transaction.
}
val stmt = insertStatement(conn, table, rddSchema)
try {
var rowCount = 0
Expand Down Expand Up @@ -175,14 +187,18 @@ object JdbcUtils extends Logging {
} finally {
stmt.close()
}
conn.commit()
if (supportsTransactions) {
conn.commit()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still wrong... The commit is partition level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the dataFrame has duplicate keys and the target tables have the unique constraints, we could see the non-deterministic results at the target tables, since some partitions containing duplicate keys could be rolled back.

}
committed = true
} finally {
if (!committed) {
// The stage must fail. We got here through an exception path, so
// let the exception through unless rollback() or close() want to
// tell the user about another problem.
conn.rollback()
if (supportsTransactions) {
conn.rollback()
}
conn.close()
} else {
// The stage must succeed. We cannot propagate any exception close() might throw.
Expand Down