Skip to main content

Oracle Provider

The Oracle provider brings Excalibur's reliable-persistence subsystems to Oracle Database. It offers Dapper-based event sourcing, outbox, inbox, and saga stores over the managed Oracle.ManagedDataAccess.Core driver — behind the same store abstractions used by every other provider, so your application code is unchanged.

The Oracle packages are opt-in: install only the subsystems you use, and register each with its AddOracle* / UseOracle extension.

Before You Start

Packages

PackageRegistersSubsystem
Excalibur.EventSourcing.OracleIEventStore, ISnapshotStoreEvent sourcing
Excalibur.Outbox.OracleOracle outbox storeOutbox pattern
Excalibur.Inbox.OracleIInboxStoreInbox pattern
Excalibur.Saga.OracleISagaStore, saga timeout storeSagas

Common dependencies: Oracle.ManagedDataAccess.Core, Dapper

Event Sourcing

dotnet add package Excalibur.EventSourcing.Oracle

Register the event store and (optionally) the snapshot store with a connection factory:

using Microsoft.Extensions.DependencyInjection;
using Oracle.ManagedDataAccess.Client;

services.AddOracleEventStore(
() => new OracleConnection(connectionString),
schema: "EXCALIBUR",
table: "EVENTSTOREEVENTS");

services.AddOracleSnapshotStore(
() => new OracleConnection(connectionString),
schema: "EXCALIBUR",
table: "EVENTSTORESNAPSHOTS");

Or configure via options, validated at startup:

services.AddOracleEventStore(options =>
{
options.ConnectionString = connectionString;
options.Schema = "EXCALIBUR";
options.Table = "EVENTSTOREEVENTS";
});

Batch appends are atomic — a multi-row append is all-or-nothing, so a mid-batch failure never leaves a torn event-stream prefix.

Outbox

dotnet add package Excalibur.Outbox.Oracle

The Oracle outbox is registered through the outbox builder with UseOracle:

services.AddExcalibur(x => x.AddOutbox(outbox =>
{
outbox.UseOracle(oracle =>
{
oracle.ConnectionString(connectionString)
.SchemaName("messaging")
.TableName("outbox_messages")
.ReservationTimeout(TimeSpan.FromMinutes(10))
.MaxAttempts(5);
})
.EnableBackgroundProcessing();
}));

A connection can also be resolved from the container via ConnectionFactory(sp => ...).

Inbox

dotnet add package Excalibur.Inbox.Oracle
services.AddOracleInboxStore(options =>
{
options.ConnectionString = connectionString;
options.SchemaName = "messaging";
options.TableName = "inbox_messages";
});

An overload accepts a connection-factory provider (Func<IServiceProvider, Func<OracleConnection>>) when the connection is built from other registered services.

Sagas

dotnet add package Excalibur.Saga.Oracle
services.AddOracleSagaStore(options =>
{
options.ConnectionString = connectionString;
options.SchemaName = "sagas";
});

// Optional: durable saga timeouts
services.AddOracleSagaTimeoutStore(options =>
{
options.ConnectionString = connectionString;
});

Completed sagas can be purged on a retention window via the saga automatic-cleanup background service (SagaOptions.EnableAutomaticCleanup), consistent with the other saga providers. See Sagas → Retention & Cleanup.

SQL Injection Protection

Schema and table names supplied via configuration are validated and quoted, so they cannot be used to inject SQL — the same protection applied by the SQL Server and PostgreSQL providers.

What's Next