@Test
  public void testNonColocatedTX() {
    Host host = Host.getHost(0);
    VM accessor = host.getVM(0);
    VM datastore1 = host.getVM(1);
    VM datastore2 = host.getVM(2);

    datastore2.invoke(new SerializableCallable<Object>() {
      @Override
      public Object call() {
        createRegion(false, 1, null);
        return null;
      }
    });

    initAccessorAndDataStore(accessor, datastore1, 1);

    accessor.invoke(new SerializableCallable<Object>() {
      @Override
      public Object call() {
        Region<CustId, Customer> custRegion = getCache().getRegion(CUSTOMER);
        Region<OrderId, Order> orderRegion = getCache().getRegion(ORDER);
        CacheTransactionManager mgr = getCache().getTxManager();
        mgr.begin();
        assertThatThrownBy(() -> put10Entries(custRegion, orderRegion))
            .isInstanceOf(TransactionDataNotColocatedException.class);
        mgr.rollback();
        put10Entries(custRegion, orderRegion);

        mgr.begin();

        assertThatThrownBy(() -> put10Entries(custRegion, orderRegion))
            .isInstanceOf(TransactionDataNotColocatedException.class);
        mgr.rollback();
        return null;
      }

      private void put10Entries(Region custRegion, Region orderRegion) {
        for (int i = 0; i < 10; i++) {
          CustId custId = new CustId(i);
          Customer customer = new Customer("customer" + i, "address" + i);
          OrderId orderId = new OrderId(i, custId);
          Order order = new Order("order" + i);
          custRegion.put(custId, customer);
          orderRegion.put(orderId, order);
        }
      }
    });
  }
When we have narrowed down on a target node for a transaction, test that we throw an exception
if that node does not host primary for subsequent entries
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/RemoteTransactionDUnitTest.java