@@ -135,7 +135,7 @@ public interface DatabaseClient {
135
135
ReadOnlyTransaction singleUseReadOnlyTransaction ();
136
136
137
137
/**
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
139
139
* given timestamp bound. This method differs from {@link #singleUse(TimestampBound)} in that the
140
140
* read timestamp used may be inspected after the read has returned data or finished successfully.
141
141
*
@@ -269,4 +269,53 @@ public interface DatabaseClient {
269
269
*
270
270
*/
271
271
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 );
272
321
}
0 commit comments