Hi Alan,
For normal cluster operations, you would want to use TransactionServiceClient. This is the regular distributed implementation of TransactionSystemClient. If you really don't need ZK discovery (it's also used to handle transparent failover between active TransactionService instances), you should be able to pass null for a DiscoveryServiceClient when setting up the client instance:
Configuration conf = new Configuration();
// pass in the transaction service location
conf.set(TxConstants.Service.CFG_DATA_TX_BIND_ADDRESS, "<tx service hostname>");
// if overriding default port
conf.set(TxConstants.Service.CFG_DATA_TX_BIND_PORT, "<port>");
ThriftClientProvider clientProvider = new PooledClientProvider(conf, null);
TransactionServiceClient txClient = new TransactionServiceClient(conf, clientProvider);
This bypasses the use of ZK for service discovery and reads the TransactionService address from the provided configuration.
From here you can construct a TransactionContext and use that to control the transaction lifecycle.
Gary