Skip to main content

Java Read/Write Routing Boundary

Evidence boundary: the routing contracts below were verified from teaql-core/teaql-runtime 1.525-RELEASE JAR signatures and bytecode. No primary/replica topology has been executed in the maintained Java Golden Path.

TeaQL dispatches reads and writes through separate executor interfaces, but it does not automatically provide a replica-consistency policy.

Runtime Dispatch

For every query or mutation, runtime resolves the entity descriptor's dataService value, falling back to default, then calls the matching registry method:

OperationRegistry methodExecutor receives
Query/aggregationresolveQueryExecutor(name)UserContext, QueryRequest
Insert/update/delete/recoverresolveMutationExecutor(name)UserContext, MutationRequest
Transaction boundaryresolveTransactionExecutor(name)UserContext, callback

The exact Java interfaces are DataServiceRegistry, QueryExecutor, MutationExecutor, and TransactionExecutor.

Why a Custom Registry Is Required

DefaultDataServiceRegistry stores one DataServiceExecutor per route name and casts that object to the requested executor interface. Registering a primary executor and then a replica executor under the same name does not form a pair; one registration replaces the other.

A split deployment needs a custom DataServiceRegistry that returns:

  • a context-aware query router for resolveQueryExecutor;
  • the primary mutation executor for resolveMutationExecutor;
  • the primary transaction executor for resolveTransactionExecutor.

Mount it with TeaQLRuntime.builder().registry(...).

Request-Scoped Consistency

Every executor method receives UserContext. UserContext.extension(name) and put(name, value) are the released request-state boundary that a project can use for a primary-sticky flag.

The routing query executor should choose primary when:

  • a successful mutation already occurred in the context;
  • a write transaction is active;
  • the operation makes an authorization, uniqueness, or locking decision;
  • the caller explicitly requests strong consistency;
  • replica health or measured lag violates the endpoint policy.

The mutation wrapper should set the sticky flag only after the primary mutation succeeds. Application context lifecycle must prevent that state leaking into an unrelated request.

No Built-In Method Names

Methods such as useReadOnlyRoute, markWriteHappened, putLocalStorage, or a project DataSourceKey are not verified teaql-java 1.525-RELEASE APIs. They may exist in an application, but current TeaQL documentation should not present them as runtime methods.

Operational Requirements

  • Define a measurable replication-lag budget per endpoint.
  • Keep mutations, transactions, schema, ID allocation, locks, and critical authorization reads on primary.
  • Decide whether replica failure falls back to primary or fails closed.
  • Monitor route selection, lag, fallback, saturation, and timeouts.
  • Test transaction connection ownership; a routing flag alone does not prove that several operations share one database transaction.
  • Never route writes to a replica during failover.

See Configure Read/Write Splitting for an implementation skeleton and integration test matrix.