@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(); }
/** Example of getting entities for several keys. */ // [TARGET get(Key...)] // [VARIABLE "my_first_key_name"] // [VARIABLE "my_second_key_name"] public List<Entity> getMultiple(String firstKeyName, String secondKeyName) { Datastore datastore = transaction.getDatastore(); // TODO change so that it's not necessary to hold the entities in a list for integration testing // [START getMultiple] KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); Key firstKey = keyFactory.newKey(firstKeyName); Key secondKey = keyFactory.newKey(secondKeyName); Iterator<Entity> entitiesIterator = transaction.get(firstKey, secondKey); List<Entity> entities = Lists.newArrayList(); while (entitiesIterator.hasNext()) { Entity entity = entitiesIterator.next(); // do something with the entity entities.add(entity); } transaction.commit(); // [END getMultiple] return entities; }
@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(); }
/** Example of getting an entity for a given key. */ // [TARGET get(Key)] // [VARIABLE "my_key_name"] public Entity get(String keyName) { Datastore datastore = transaction.getDatastore(); // [START get] Key key = datastore.newKeyFactory().setKind("MyKind").newKey(keyName); Entity entity = transaction.get(key); transaction.commit(); // Do something with the entity // [END get] return entity; }
transaction.commit(); } catch (Throwable t) { transaction.rollback();
/** Example of fetching a list of entities for several keys. */ // [TARGET fetch(Key...)] // [VARIABLE "my_first_key_name"] // [VARIABLE "my_second_key_name"] public List<Entity> fetchEntitiesWithKeys(String firstKeyName, String secondKeyName) { Datastore datastore = transaction.getDatastore(); // [START fetchEntitiesWithKeys] KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); Key firstKey = keyFactory.newKey(firstKeyName); Key secondKey = keyFactory.newKey(secondKeyName); List<Entity> entities = transaction.fetch(firstKey, secondKey); for (Entity entity : entities) { // do something with the entity } transaction.commit(); // [END fetchEntitiesWithKeys] return entities; }
/** Example of deleting multiple entities. */ // [TARGET delete(Key...)] // [VARIABLE "my_key_name1"] // [VARIABLE "my_key_name2"] public void multipleDeleteEntities(String keyName1, String keyName2) { Datastore datastore = transaction.getDatastore(); // [START multipleDeleteEntities] Key key1 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName1); Key key2 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName2); transaction.delete(key1, key2); transaction.commit(); // [END multipleDeleteEntities] }
/** Example of putting a single entity. */ // [TARGET put(FullEntity)] // [VARIABLE "my_key_name"] public void putSingleEntity(String keyName) { Datastore datastore = transaction.getDatastore(); // [START putSingleEntity] Key key = datastore.newKeyFactory().setKind("MyKind").newKey(keyName); Entity.Builder entityBuilder = Entity.newBuilder(key); entityBuilder.set("propertyName", "value"); Entity entity = entityBuilder.build(); transaction.put(entity); transaction.commit(); // [END putSingleEntity] }
/** Example of adding a single entity. */ // [TARGET add(FullEntity)] // [VARIABLE "my_key_name"] public void addSingleEntity(String keyName) { Datastore datastore = transaction.getDatastore(); // [START addSingleEntity] Key key = datastore.newKeyFactory().setKind("MyKind").newKey(keyName); Entity.Builder entityBuilder = Entity.newBuilder(key); entityBuilder.set("propertyName", "value"); Entity entity = entityBuilder.build(); transaction.add(entity); transaction.commit(); // [END addSingleEntity] }
/** Example of committing a transaction. */ // [TARGET commit()] public Key commit() { Datastore datastore = transaction.getDatastore(); // [START commit] // create an entity KeyFactory keyFactory = datastore.newKeyFactory().setKind("MyKind"); Key key = datastore.allocateId(keyFactory.newKey()); Entity entity = Entity.newBuilder(key).set("description", "commit()").build(); // add the entity and commit try { transaction.put(entity); transaction.commit(); } catch (DatastoreException ex) { // handle exception } // [END commit] return key; }
@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()); } } } }
@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); }
/** Example of adding multiple entities. */ // [TARGET add(FullEntity...)] // [VARIABLE "my_key_name1"] // [VARIABLE "my_key_name2"] public void multipleAddEntities(String keyName1, String keyName2) { Datastore datastore = transaction.getDatastore(); // [START multipleAddEntities] Key key1 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName1); Entity.Builder entityBuilder1 = Entity.newBuilder(key1); entityBuilder1.set("propertyName", "value1"); Entity entity1 = entityBuilder1.build(); Key key2 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName2); Entity.Builder entityBuilder2 = Entity.newBuilder(key2); entityBuilder2.set("propertyName", "value2"); Entity entity2 = entityBuilder2.build(); transaction.add(entity1, entity2); transaction.commit(); // [END multipleAddEntities] }
/** Example of updating multiple entities. */ // [TARGET update(Entity...)] // [VARIABLE "my_key_name1"] // [VARIABLE "my_key_name2"] public void multipleUpdateEntities(String keyName1, String keyName2) { Datastore datastore = transaction.getDatastore(); // [START multipleUpdateEntities] Key key1 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName1); Entity.Builder entityBuilder1 = Entity.newBuilder(key1); entityBuilder1.set("propertyName", "value3"); Entity entity1 = entityBuilder1.build(); Key key2 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName2); Entity.Builder entityBuilder2 = Entity.newBuilder(key2); entityBuilder2.set("propertyName", "value4"); Entity entity2 = entityBuilder2.build(); transaction.update(entity1, entity2); transaction.commit(); // [END multipleUpdateEntities] }
/** Example of putting multiple entities. */ // [TARGET put(FullEntity...)] // [VARIABLE "my_key_name1"] // [VARIABLE "my_key_name2"] public void multiplePutEntities(String keyName1, String keyName2) { Datastore datastore = transaction.getDatastore(); // [START multiplePutEntities] Key key1 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName1); Entity.Builder entityBuilder1 = Entity.newBuilder(key1); entityBuilder1.set("propertyName", "value1"); Entity entity1 = entityBuilder1.build(); Key key2 = datastore.newKeyFactory().setKind("MyKind").newKey(keyName2); Entity.Builder entityBuilder2 = Entity.newBuilder(key2); entityBuilder2.set("propertyName", "value2"); Entity entity2 = entityBuilder2.build(); transaction.put(entity1, entity2); transaction.commit(); // [END multiplePutEntities] }
/** Example of adding multiple entities with deferred id allocation. */ // [TARGET addWithDeferredIdAllocation(FullEntity...)] public List<Key> multipleAddEntitiesDeferredId() { Datastore datastore = transaction.getDatastore(); // [START multipleAddEntitiesDeferredId] IncompleteKey key1 = datastore.newKeyFactory().setKind("MyKind").newKey(); FullEntity.Builder entityBuilder1 = FullEntity.newBuilder(key1); entityBuilder1.set("propertyName", "value1"); FullEntity entity1 = entityBuilder1.build(); IncompleteKey key2 = datastore.newKeyFactory().setKind("MyKind").newKey(); FullEntity.Builder entityBuilder2 = FullEntity.newBuilder(key2); entityBuilder2.set("propertyName", "value2"); FullEntity entity2 = entityBuilder2.build(); transaction.addWithDeferredIdAllocation(entity1, entity2); Response response = transaction.commit(); // [END multipleAddEntitiesDeferredId] return response.getGeneratedKeys(); }
/** Example of putting multiple entities with deferred id allocation. */ // [TARGET putWithDeferredIdAllocation(FullEntity...)] public List<Key> multiplePutEntitiesDeferredId() { Datastore datastore = transaction.getDatastore(); // [START multiplePutEntitiesDeferredId] IncompleteKey key1 = datastore.newKeyFactory().setKind("MyKind").newKey(); FullEntity.Builder entityBuilder1 = FullEntity.newBuilder(key1); entityBuilder1.set("propertyName", "value1"); FullEntity entity1 = entityBuilder1.build(); IncompleteKey key2 = datastore.newKeyFactory().setKind("MyKind").newKey(); FullEntity.Builder entityBuilder2 = FullEntity.newBuilder(key2); entityBuilder2.set("propertyName", "value2"); FullEntity entity2 = entityBuilder2.build(); transaction.putWithDeferredIdAllocation(entity1, entity2); Response response = transaction.commit(); // [END multiplePutEntitiesDeferredId] return response.getGeneratedKeys(); }
@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 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()); } }