@Override public <T extends DataModel> void create(UUID jobId, String key, T model) throws IOException { Preconditions.checkNotNull(jobId); Transaction transaction = datastore.newTransaction(); Key fullKey = getDataKey(jobId, key); Entity shouldNotExist = transaction.get(fullKey); if (shouldNotExist != null) { transaction.rollback(); throw new IOException( "Record already exists for key: " + fullKey.getName() + ". Record: " + shouldNotExist); } String serialized = objectMapper.writeValueAsString(model); Entity entity = Entity.newBuilder(fullKey) .set(CREATED_FIELD, Timestamp.now()) .set(model.getClass().getName(), serialized) .build(); try { transaction.put(entity); } catch (DatastoreException e) { throw new IOException( "Could not create initial record for jobID: " + jobId + ". Record: " + entity, e); } transaction.commit(); }
@Override public <T extends DataModel> void update(UUID jobId, String key, T model) { Transaction transaction = datastore.newTransaction(); Key entityKey = getDataKey(jobId, key); try { Entity previousEntity = transaction.get(entityKey); if (previousEntity == null) { throw new IOException("Could not find record for data key: " + entityKey.getName()); } String serialized = objectMapper.writeValueAsString(model); Entity entity = Entity.newBuilder(entityKey) .set(CREATED_FIELD, Timestamp.now()) .set(model.getClass().getName(), serialized) .build(); transaction.put(entity); transaction.commit(); } catch (IOException t) { transaction.rollback(); throw new RuntimeException("Failed atomic update of key: " + key, t); } }
/** * Inserts a new {@link PortabilityJob} keyed by {@code jobId} in Datastore. * * <p>To update an existing {@link PortabilityJob} instead, use {@link JobStore#update}. * * @throws IOException if a job already exists for {@code jobId}, or if there was a different * problem inserting the job. */ @Override public void createJob(UUID jobId, PortabilityJob job) throws IOException { Preconditions.checkNotNull(jobId); Transaction transaction = datastore.newTransaction(); Entity shouldNotExist = transaction.get(getKey(jobId)); if (shouldNotExist != null) { transaction.rollback(); throw new IOException( "Record already exists for jobID: " + jobId + ". Record: " + shouldNotExist); } Entity entity = createEntity(jobId, job.toMap()); try { transaction.put(entity); } catch (DatastoreException e) { transaction.rollback(); throw new IOException( "Could not create initial record for jobID: " + jobId + ". Record: " + entity, e); } transaction.commit(); }
Transaction tx = datastore.newTransaction(); Object request; try {
throws IOException { Preconditions.checkNotNull(jobId); Transaction transaction = datastore.newTransaction(); Key key = getKey(jobId);
@Override public T call() throws DatastoreException { transaction = datastore.newTransaction(options); try { T value = callable.run(transaction); transaction.commit(); return value; } catch (Exception ex) { transaction.rollback(); throw DatastoreException.propagateUserException(ex); } finally { if (transaction.isActive()) { transaction.rollback(); } if (options != null && options.getModeCase().equals(TransactionOptions.ModeCase.READ_WRITE)) { setPrevTransactionId(transaction.getTransactionId()); } } } }
@Override public AsyncTransaction newTransaction(final Runnable afterCommit) { return new AsyncTransactionImpl(datastore.newTransaction(), afterCommit); } }
@Test public void testNewTransactionCommit() { Transaction transaction = datastore.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); transaction.update(entity2); transaction.delete(KEY1); transaction.commit(); List<Entity> list = datastore.fetch(KEY1, KEY2, KEY3); assertNull(list.get(0)); assertEquals(entity2, list.get(1)); assertEquals(ENTITY3, list.get(2)); assertEquals(3, list.size()); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException ex) { // expected to fail } try { transaction.rollback(); fail("Expecting a failure"); } catch (DatastoreException ex) { // expected to fail } verifyNotUsable(transaction); }
@Test public void testTransactionWithRead() { Transaction transaction = datastore.newTransaction(); assertNull(transaction.get(KEY3)); transaction.add(ENTITY3); transaction.commit(); assertEquals(ENTITY3, datastore.get(KEY3)); transaction = datastore.newTransaction(); assertEquals(ENTITY3, transaction.get(KEY3)); // update entity3 during the transaction datastore.put(Entity.newBuilder(ENTITY3).clear().build()); transaction.update(ENTITY2); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("ABORTED", expected.getReason()); } }
@Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) .clear() .setNull("bla") .set("list3", StringValue.of("bla"), StringValue.newBuilder("bla").build()) .build(); transaction.update(entity2); transaction.delete(KEY1); transaction.rollback(); transaction.rollback(); // should be safe to repeat rollback calls try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException ex) { // expected to fail } verifyNotUsable(transaction); List<Entity> list = datastore.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); assertEquals(3, list.size()); }
@Test public void testNewTransactionRollback() { Transaction transaction = DATASTORE.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) .clear() .setNull("bla") .set("list3", StringValue.of("bla"), StringValue.newBuilder("bla").build()) .build(); transaction.update(entity2); transaction.delete(KEY1); transaction.rollback(); transaction.rollback(); // should be safe to repeat rollback calls try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("FAILED_PRECONDITION", expected.getReason()); } List<Entity> list = DATASTORE.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); assertEquals(3, list.size()); }
@Test public void testNewTransactionCommit() { Transaction transaction = DATASTORE.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2).clear().setNull("bla").build(); transaction.update(entity2); transaction.delete(KEY1); transaction.commit(); assertFalse(transaction.isActive()); List<Entity> list = DATASTORE.fetch(KEY1, KEY2, KEY3); assertNull(list.get(0)); assertEquals(entity2, list.get(1)); assertEquals(ENTITY3, list.get(2)); assertEquals(3, list.size()); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("FAILED_PRECONDITION", expected.getReason()); } try { transaction.rollback(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("FAILED_PRECONDITION", expected.getReason()); } }
@Test public void testTransactionWithRead() { Transaction transaction = DATASTORE.newTransaction(); assertNull(transaction.get(KEY3)); transaction.add(ENTITY3); transaction.commit(); assertEquals(ENTITY3, DATASTORE.get(KEY3)); transaction = DATASTORE.newTransaction(); assertEquals(ENTITY3, transaction.get(KEY3)); // update entity3 during the transaction DATASTORE.put(Entity.newBuilder(ENTITY2).clear().set("from", "datastore").build()); transaction.update(Entity.newBuilder(ENTITY2).clear().set("from", "transaction").build()); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("ABORTED", expected.getReason()); } }
@Test public void testTransactionWithQuery() { Query<Entity> query = Query.newEntityQueryBuilder() .setKind(KIND2) .setFilter(PropertyFilter.hasAncestor(KEY2)) .build(); Transaction transaction = datastore.newTransaction(); QueryResults<Entity> results = transaction.run(query); assertEquals(ENTITY2, results.next()); assertFalse(results.hasNext()); transaction.add(ENTITY3); transaction.commit(); assertEquals(ENTITY3, datastore.get(KEY3)); transaction = datastore.newTransaction(); results = transaction.run(query); assertEquals(ENTITY2, results.next()); transaction.delete(ENTITY3.getKey()); // update entity2 during the transaction datastore.put(Entity.newBuilder(ENTITY2).clear().build()); try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("ABORTED", expected.getReason()); } }
.setNamespace(NAMESPACE) .build(); Transaction transaction = DATASTORE.newTransaction(); QueryResults<Entity> results = transaction.run(query); assertTrue(results.hasNext()); assertEquals(ENTITY3, DATASTORE.get(KEY3)); transaction = DATASTORE.newTransaction(); results = transaction.run(query); assertTrue(results.hasNext());
/** * Marks a task entity as done. * * @param id The ID of the task entity as given by {@link Key#id()} * @return true if the task was found, false if not * @throws DatastoreException if the transaction fails */ boolean markDone(long id) { Transaction transaction = datastore.newTransaction(); try { Entity task = transaction.get(keyFactory.newKey(id)); if (task != null) { transaction.put(Entity.newBuilder(task).set("done", true).build()); } transaction.commit(); return task != null; } finally { if (transaction.isActive()) { transaction.rollback(); } } } // [END datastore_update_entity]
@Override public Transaction newTransaction(TransactionOptions transactionOptions) { return InstrumentedTransaction.of(stats, delegate.newTransaction(transactionOptions)); }
@Override public Transaction newTransaction() { return InstrumentedTransaction.of(stats, delegate.newTransaction()); }
/** * @see Datastore#newTransaction() * @throws DatastoreIOException if the underlying client throws {@link DatastoreException} */ CheckedDatastoreTransaction newTransaction() throws DatastoreIOException { try { return new CheckedDatastoreTransaction(this, datastore.newTransaction()); } catch (DatastoreException e) { throw new DatastoreIOException(e); } }
/** * Creates a new instance of <code>DatastoreTransaction</code>. * * @param entityManager * the entity manager that created this transaction. * @param transactionMode * the transaction mode */ public DefaultDatastoreTransaction(DefaultEntityManager entityManager, TransactionMode transactionMode) { this.entityManager = entityManager; this.datastore = entityManager.getDatastore(); this.nativeTransaction = datastore .newTransaction(transactionMode.getNativeTransactionOptions()); this.reader = new DefaultDatastoreReader(this); this.writer = new TransactionalWriter(this); }