@@ -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,51 @@ 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
+ * <ul>
292
+ * That said, Partitioned DML is not a drop-in replacement for standard DML used in {@link
293
+ * #readWriteTransaction()}.
294
+ * <li>The DML statement must be fully-partitionable. Specifically, the statement must be
295
+ * expressible as the union of many statements which each access only a single row of the
296
+ * table.
297
+ * <li>The statement is not applied atomically to all rows of the table. Rather, the statement
298
+ * is applied atomically to partitions of the table, in independent internal transactions.
299
+ * Secondary index rows are updated atomically with the base table rows.
300
+ * <li>Partitioned DML does not guarantee exactly-once execution semantics against a partition.
301
+ * The statement will be applied at least once to each partition. It is strongly recommended
302
+ * that the DML statement should be idempotent to avoid unexpected results. For instance, it
303
+ * is potentially dangerous to run a statement such as `UPDATE table SET column = column +
304
+ * 1` as it could be run multiple times against some rows.
305
+ * <li>The partitions are committed automatically - there is no support for Commit or Rollback.
306
+ * If the call returns an error, or if the client issuing the DML statement dies, it is
307
+ * possible that some rows had the statement executed on them successfully. It is also
308
+ * possible that statement was never executed against other rows.
309
+ * <li>If any error is encountered during the execution of the partitioned DML operation (for
310
+ * instance, a UNIQUE INDEX violation, division by zero, or a value that cannot be stored
311
+ * due to schema constraints), then the operation is stopped at that point and an error is
312
+ * returned. It is possible that at this point, some partitions have been committed (or even
313
+ * committed multiple times), and other partitions have not been run at all.
314
+ *
315
+ * <p>Given the above, Partitioned DML is good fit for large, database-wide, operations that are
316
+ * idempotent, such as deleting old rows from a very large table.
317
+ */
318
+ long executePartitionedUpdate (Statement stmt );
272
319
}
0 commit comments