@@ -135,7 +135,7 @@ public interface DatabaseClient {
135135 ReadOnlyTransaction singleUseReadOnlyTransaction ();
136136
137137 /**
138- * Returns a read-only transaction context in which a single read or query can be performed at the
138+ * Returns a read-only transaction context in which a single read or query can be performed at
139139 * given timestamp bound. This method differs from {@link #singleUse(TimestampBound)} in that the
140140 * read timestamp used may be inspected after the read has returned data or finished successfully.
141141 *
@@ -269,4 +269,53 @@ public interface DatabaseClient {
269269 *
270270 */
271271 TransactionManager transactionManager ();
272+
273+ /**
274+ * Returns the lower bound of rows modified by this DML statement.
275+ *
276+ * <p>The method will block until the update is complete. Running a DML statement with this method
277+ * does not offer exactly once semantics, and therfore the DML statement should be idempotent. The
278+ * DML statement must be fully-partitionable. Specifically, the statement must be expressible as
279+ * the union of many statements which each access only a single row of the table. This is a
280+ * Partitioned DML transaction in which a single Partitioned DML statement is executed.
281+ * Partitioned DML partitions the key space and runs the DML statement over each partition in
282+ * parallel using separate, internal transactions that commit independently. Partitioned DML
283+ * transactions do not need to be committed.
284+ *
285+ * <p>Partitioned DML updates are used to execute a single DML statement with a different
286+ * execution strategy that provides different, and often better, scalability properties for large,
287+ * table-wide operations than DML in a {@link #readWriteTransaction()} transaction. Smaller scoped
288+ * statements, such as an OLTP workload, should prefer using {@link
289+ * TransactionContext#executeUpdate(Statement)} with {@link #readWriteTransaction()}.
290+ *
291+ * <p>That said, Partitioned DML is not a drop-in replacement for standard DML used in {@link
292+ * #readWriteTransaction()}.</p>
293+ *
294+ * <ul>
295+ * <li>The DML statement must be fully-partitionable. Specifically, the statement must be
296+ * expressible as the union of many statements which each access only a single row of the
297+ * table.
298+ * <li>The statement is not applied atomically to all rows of the table. Rather, the statement
299+ * is applied atomically to partitions of the table, in independent internal transactions.
300+ * Secondary index rows are updated atomically with the base table rows.
301+ * <li>Partitioned DML does not guarantee exactly-once execution semantics against a partition.
302+ * The statement will be applied at least once to each partition. It is strongly recommended
303+ * that the DML statement should be idempotent to avoid unexpected results. For instance, it
304+ * is potentially dangerous to run a statement such as `UPDATE table SET column = column +
305+ * 1` as it could be run multiple times against some rows.
306+ * <li>The partitions are committed automatically - there is no support for Commit or Rollback.
307+ * If the call returns an error, or if the client issuing the DML statement dies, it is
308+ * possible that some rows had the statement executed on them successfully. It is also
309+ * possible that statement was never executed against other rows.
310+ * <li>If any error is encountered during the execution of the partitioned DML operation (for
311+ * instance, a UNIQUE INDEX violation, division by zero, or a value that cannot be stored
312+ * due to schema constraints), then the operation is stopped at that point and an error is
313+ * returned. It is possible that at this point, some partitions have been committed (or even
314+ * committed multiple times), and other partitions have not been run at all.
315+ * </ul>
316+ *
317+ * <p>Given the above, Partitioned DML is good fit for large, database-wide, operations that are
318+ * idempotent, such as deleting old rows from a very large table.
319+ */
320+ long executePartitionedUpdate (Statement stmt );
272321}
0 commit comments