Oracle Database 23ai introduces True Cache, an in-memory SQL cache designed to enhance application performance and scalability. True Cache retrieves data directly from the primary database and stores it in memory, ensuring it remains consistent and up to date within the True Cache buffer cache—without manual consistency management or invalidation, common issues with traditional external caching solutions.
Unlike traditional external caches requiring applications to be aware of cache topology, True Cache hides the complexity through Oracle Database’s dynamic service registration, streamlining cache management and reducing architectural challenges.
The connectivity to True Cache can be achieved in two ways:
Two data sources
Applications can define two (or more) Data Sources: one connecting to the primary database and one to the True Cache instances, which Connection Manager or remote listeners can optionally serve to achieve transparent load balancing, multiplexing, and simplifying the SQL*Net configuration.
The following diagram and code show an application using two Data Sources (ods_rw and ods_tc in the example):

import oracle.jdbc.datasource.impl.OracleDataSource;
OracleDataSource ods_rw = new OracleDataSource();
ods_rw.setURL(url_app_rw);
...
try (Connection conn_rw = ods_rw.getConnection()) {
// This is connected to the Primary
} catch (SQLException sqex) {
...
}
OracleDataSource ods_tc = new OracleDataSource();
ods_tc.setURL(url_app_tc);
...
try (Connection conn_tc = ods_tc.getConnection()) {
// This is connected to True Cache
} catch (SQLException sqex) {
...
}
This approach has been widely used for years in applications leveraging replicas to offload read-only workloads or when implementing the Command Query Responsibility Segregation (CQRS) pattern.
It remains the most flexible method for connecting to True Cache. An application server can choose to connect to its dedicated True Cache instance, optionally hosted within the same infrastructure, such as the same virtual machine (VM), pod, or similar environment.
One data source with transparent redirection
Applications using the JDBC Thin driver can also opt for more straightforward connectivity and code using a single data source. By default, the connection goes to the primary service. Still, whenever the connection is set to read-only, any subsequent queries are transparently redirected to the True Cache service until the read-only mode is deactivated.
The following diagram and code show an application using a single data source using the True Cache driver connection and setting the connection to read only when appropriate:

import oracle.jdbc.datasource.impl.OracleDataSource;
OracleDataSource ods = new OracleDataSource();
ods.setURL(url_app);
...
ods.setConnectionProperty(
"oracle.jdbc.useTrueCacheDriverConnection", "true");
try (Connection conn = ods.getConnection()) {
// This is connected to the Primary
conn.setReadOnly(true);
// This is connected to the True Cache
} catch (SQLException sqex) {
...
}
How does True Cache’s transparent redirection work?
The True Cache instances must register their services to the same endpoint as the primary database. That can be the primary database’s listener, SCAN listener, remote listener, Connection Manager, or Global Data Services infrastructure.
Creating the primary service serving the True Cache-enabled application takes an additional parameter corresponding to the True Cache’s service name.
srvctl add service -db APPCDB -service APP_RW -pdb APPPDB -true_cache_service APP_TC
(See Server Control Utility Reference for more information).
The package DBMS_SERVICE supports the same property for database deployments without Grid Infrastructure.
DECLARE
db_params dbms_service.svc_parameter_array;
BEGIN
db_params('true_cache_service') := 'APP_TC';
DBMS_SERVICE.CREATE_SERVICE('APP_RW', 'APP_RW', db_params);
END;
When the JDBC 23ai driver connects to the primary service, it automatically retrieves the True Cache service name and uses it to establish a connection to the same endpoint where the True Cache service is registered.
To enable this functionality, the OracleDataSource connection must have the useTrueCacheDriverConnection property set:
ods1.setConnectionProperty("oracle.jdbc.useTrueCacheDriverConnection", "true");
At this point, whenever the application sets the connection to read-only:
java.sql.Connection.setReadOnly(true);
The driver transparently sends the requests to the True Cache service.
When using Maven, make sure you use the latest driver (23.7.0.25.01 at the time of writing):
<dependencies>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.7.0.25.01</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ucp11</artifactId>
<version>23.7.0.25.01</version>
</dependency>
</dependencies>
True Cache redirection works for Active Data Guard, too!
Imagine if the JDBC driver could seamlessly redirect read-only statements to Active Data Guard standby databases, just as it does for True Cache instances. Good news—it can! The redirection works at the JDBC, service, and listener levels, so True Cache isn’t a requirement.
You can configure the read-write primary database service for True Cache to point to the read-only service used by the Active Data Guard. Your Active Data Guard standby database(s) need to register their read-only service to the same listener endpoint as the primary database (again: remote listener, SCAN, CMAN, or GDS will work) and start developing using java.sql.Connection.setReadOnly(boolean) when needed.
However, each read/write service can only have one True Cache service, which means you can’t mix Active Data Guard and True Cache without using multiple application Data Sources.
The following diagram, very similar to the previous one, shows that a True Cache driver connection transparently works with an Active Data Guard standby database:

More information:
Oracle True Cache User’s Guide – 2.3.3 Configuring True Cache Database Application Services Manually
What’s in it for developers?
By leveraging True Cache and JDBC redirection, developers can achieve a more efficient, high-performance architecture without the complexities of traditional caching solutions. True Cache eliminates the need for external caches requiring manual invalidation and consistency checks, providing an up-to-date, in-memory SQL cache directly integrated with the database. Meanwhile, JDBC redirection simplifies connection management by seamlessly routing read-only queries to True Cache or Active Data Guard standby databases, optimizing resource utilization without requiring application changes. This approach enhances scalability and response times without introducing operational overhead, making building resilient, database-driven applications easier.
Many thanks to Sebastian Solbach for inspiring this blog.
