Skip to content

Commit

Permalink
Add transaction isolation level support (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
Arkatufus authored Apr 24, 2023
1 parent 97ae536 commit aeba095
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ namespace Akka.Persistence.Hosting
public Akka.Persistence.Hosting.AkkaPersistenceJournalBuilder AddWriteEventAdapter<TAdapter>(string eventAdapterName, System.Collections.Generic.IEnumerable<System.Type> boundTypes)
where TAdapter : Akka.Persistence.Journal.IWriteEventAdapter { }
}
public static class Extensions
{
public static string ToHocon(this System.Data.IsolationLevel level) { }
public static string ToHocon(this System.Data.IsolationLevel? level) { }
}
public abstract class JournalOptions
{
protected JournalOptions(bool isDefault) { }
Expand Down Expand Up @@ -64,19 +69,23 @@ namespace Akka.Persistence.Hosting
public string ConnectionString { get; set; }
public System.TimeSpan ConnectionTimeout { get; set; }
public abstract string MetadataTableName { get; set; }
public abstract System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public abstract string SchemaName { get; set; }
public abstract bool SequentialAccess { get; set; }
public abstract string TableName { get; set; }
public abstract System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
public abstract class SqlSnapshotOptions : Akka.Persistence.Hosting.SnapshotOptions
{
protected SqlSnapshotOptions(bool isDefault) { }
public string ConnectionString { get; set; }
public System.TimeSpan ConnectionTimeout { get; set; }
public abstract System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public abstract string SchemaName { get; set; }
public abstract bool SequentialAccess { get; set; }
public abstract string TableName { get; set; }
public abstract System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ namespace Akka.Persistence.PostgreSql.Hosting
public bool UseBigIntIdentityForOrderingColumn { get; set; }
public override string Identifier { get; set; }
public override string MetadataTableName { get; set; }
public override System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public override string SchemaName { get; set; }
public override bool SequentialAccess { get; set; }
public override string TableName { get; set; }
public override System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
public sealed class PostgreSqlSnapshotOptions : Akka.Persistence.Hosting.SqlSnapshotOptions
Expand All @@ -28,9 +30,11 @@ namespace Akka.Persistence.PostgreSql.Hosting
protected override Akka.Configuration.Config InternalDefaultConfig { get; }
public Akka.Persistence.PostgreSql.StoredAsType StoredAs { get; set; }
public override string Identifier { get; set; }
public override System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public override string SchemaName { get; set; }
public override bool SequentialAccess { get; set; }
public override string TableName { get; set; }
public override System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
public static class StoredAsExtensions { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ namespace Akka.Persistence.SqlServer.Hosting
public bool UseConstantParameterSize { get; set; }
public override string Identifier { get; set; }
public override string MetadataTableName { get; set; }
public override System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public override string SchemaName { get; set; }
public override bool SequentialAccess { get; set; }
public override string TableName { get; set; }
public override System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
public sealed class SqlServerSnapshotOptions : Akka.Persistence.Hosting.SqlSnapshotOptions
Expand All @@ -28,9 +30,11 @@ namespace Akka.Persistence.SqlServer.Hosting
protected override Akka.Configuration.Config InternalDefaultConfig { get; }
public bool UseConstantParameterSize { get; set; }
public override string Identifier { get; set; }
public override System.Data.IsolationLevel ReadIsolationLevel { get; set; }
public override string SchemaName { get; set; }
public override bool SequentialAccess { get; set; }
public override string TableName { get; set; }
public override System.Data.IsolationLevel WriteIsolationLevel { get; set; }
protected override System.Text.StringBuilder Build(System.Text.StringBuilder sb) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ private static void AssertJournalConfig(Config underTest, Config reference)
AssertBoolean(underTest, reference, "sequential-access");
AssertString(underTest, reference, "stored-as");
AssertBoolean(underTest, reference, "use-bigint-identity-for-ordering-column");
AssertString(underTest, reference, "read-isolation-level");
AssertString(underTest, reference, "write-isolation-level");
}

private static void AssertSnapshotConfig(Config underTest, Config reference)
Expand All @@ -320,6 +322,8 @@ private static void AssertSnapshotConfig(Config underTest, Config reference)
AssertBoolean(underTest, reference, "auto-initialize");
AssertBoolean(underTest, reference, "sequential-access");
AssertBoolean(underTest, reference, "use-constant-parameter-size");
AssertString(underTest, reference, "read-isolation-level");
AssertString(underTest, reference, "write-isolation-level");
}

private static void AssertString(Config underTest, Config reference, string hoconPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ private static void AssertJournalConfig(Config underTest, Config reference)
AssertString(underTest, reference, "metadata-table-name");
AssertBoolean(underTest, reference, "sequential-access");
AssertBoolean(underTest, reference, "use-constant-parameter-size");
AssertString(underTest, reference, "read-isolation-level");
AssertString(underTest, reference, "write-isolation-level");
}

private static void AssertSnapshotConfig(Config underTest, Config reference)
Expand All @@ -326,6 +328,8 @@ private static void AssertSnapshotConfig(Config underTest, Config reference)
AssertBoolean(underTest, reference, "auto-initialize");
AssertBoolean(underTest, reference, "sequential-access");
AssertBoolean(underTest, reference, "use-constant-parameter-size");
AssertString(underTest, reference, "read-isolation-level");
AssertString(underTest, reference, "write-isolation-level");
}

private static void AssertString(Config underTest, Config reference, string hoconPath)
Expand Down
41 changes: 41 additions & 0 deletions src/Akka.Persistence.Hosting/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// -----------------------------------------------------------------------
// <copyright file="Extensions.cs" company="Akka.NET Project">
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Runtime.CompilerServices;
using Akka.Hosting;

namespace Akka.Persistence.Hosting
{
public static class Extensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string ToHocon(this IsolationLevel? level)
{
if (level is null)
throw new ArgumentNullException(nameof(level));
return level.Value.ToHocon();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string ToHocon(this IsolationLevel level)
{
return level switch
{
IsolationLevel.Unspecified => "unspecified".ToHocon(),
IsolationLevel.ReadCommitted => "read-committed".ToHocon(),
IsolationLevel.ReadUncommitted => "read-uncommitted".ToHocon(),
IsolationLevel.RepeatableRead => "repeatable-read".ToHocon(),
IsolationLevel.Serializable => "serializable".ToHocon(),
IsolationLevel.Snapshot => "snapshot".ToHocon(),
IsolationLevel.Chaos => "chaos".ToHocon(),
_ => throw new IndexOutOfRangeException($"Unknown IsolationLevel value: {level}"),
};
}

}
}
30 changes: 30 additions & 0 deletions src/Akka.Persistence.Hosting/SqlJournalOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Text;
using Akka.Hosting;

Expand Down Expand Up @@ -70,6 +71,32 @@ protected SqlJournalOptions(bool isDefault): base(isDefault)
/// </summary>
public abstract bool SequentialAccess { get; set; }

/// <summary>
/// <para>
/// The <see cref="IsolationLevel"/> of all database read query.
/// </para>
/// <para>
/// <see cref="IsolationLevel"/> documentation can be read
/// <a href="https://learn.microsoft.com/en-us/dotnet/api/system.data.isolationlevel?#fields">here</a>
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </summary>
public abstract IsolationLevel ReadIsolationLevel { get; set; }

/// <summary>
/// <para>
/// The <see cref="IsolationLevel"/> of all database write query.
/// </para>
/// <para>
/// <see cref="IsolationLevel"/> documentation can be read
/// <a href="https://learn.microsoft.com/en-us/dotnet/api/system.data.isolationlevel?#fields">here</a>
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </summary>
public abstract IsolationLevel WriteIsolationLevel { get; set; }

protected override StringBuilder Build(StringBuilder sb)
{
sb.AppendLine($"connection-string = {ConnectionString.ToHocon()}");
Expand All @@ -78,6 +105,9 @@ protected override StringBuilder Build(StringBuilder sb)
sb.AppendLine($"table-name = {TableName.ToHocon()}");
sb.AppendLine($"metadata-table-name = {MetadataTableName.ToHocon()}");
sb.AppendLine($"sequential-access = {SequentialAccess.ToHocon()}");

sb.AppendLine($"read-isolation-level = {ReadIsolationLevel.ToHocon()}");
sb.AppendLine($"write-isolation-level = {WriteIsolationLevel.ToHocon()}");

return base.Build(sb);
}
Expand Down
30 changes: 30 additions & 0 deletions src/Akka.Persistence.Hosting/SqlSnapshotOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Text;
using Akka.Hosting;

Expand Down Expand Up @@ -59,13 +60,42 @@ protected SqlSnapshotOptions(bool isDefault): base(isDefault)
/// </summary>
public abstract bool SequentialAccess { get; set; }

/// <summary>
/// <para>
/// The <see cref="IsolationLevel"/> of all database read query.
/// </para>
/// <para>
/// <see cref="IsolationLevel"/> documentation can be read
/// <a href="https://learn.microsoft.com/en-us/dotnet/api/system.data.isolationlevel?#fields">here</a>
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </summary>
public abstract IsolationLevel ReadIsolationLevel { get; set; }

/// <summary>
/// <para>
/// The <see cref="IsolationLevel"/> of all database write query.
/// </para>
/// <para>
/// <see cref="IsolationLevel"/> documentation can be read
/// <a href="https://learn.microsoft.com/en-us/dotnet/api/system.data.isolationlevel?#fields">here</a>
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </summary>
public abstract IsolationLevel WriteIsolationLevel { get; set; }

protected override StringBuilder Build(StringBuilder sb)
{
sb.AppendLine($"connection-string = {ConnectionString.ToHocon()}");
sb.AppendLine($"connection-timeout = {ConnectionTimeout.ToHocon()}");
sb.AppendLine($"schema-name = {SchemaName.ToHocon()}");
sb.AppendLine($"table-name = {TableName.ToHocon()}");
sb.AppendLine($"sequential-access = {SequentialAccess.ToHocon()}");

sb.AppendLine($"read-isolation-level = {ReadIsolationLevel.ToHocon()}");
sb.AppendLine($"write-isolation-level = {WriteIsolationLevel.ToHocon()}");

return base.Build(sb);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Text;
using Akka.Configuration;
using Akka.Persistence.Hosting;
Expand Down Expand Up @@ -95,6 +96,12 @@ public PostgreSqlJournalOptions(bool isDefaultPlugin, string identifier = "postg
/// </summary>
public bool UseBigIntIdentityForOrderingColumn { get; set; } = false;

/// <inheritdoc/>
public override IsolationLevel ReadIsolationLevel { get; set; } = IsolationLevel.Unspecified;

/// <inheritdoc/>
public override IsolationLevel WriteIsolationLevel { get; set; } = IsolationLevel.Unspecified;

protected override Config InternalDefaultConfig => Default;

protected override StringBuilder Build(StringBuilder sb)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Text;
using Akka.Configuration;
using Akka.Persistence.Hosting;
Expand Down Expand Up @@ -78,6 +79,12 @@ public PostgreSqlSnapshotOptions(bool isDefaultPlugin, string identifier = "post
/// </summary>
public StoredAsType StoredAs { get; set; } = StoredAsType.ByteA;

/// <inheritdoc/>
public override IsolationLevel ReadIsolationLevel { get; set; } = IsolationLevel.Unspecified;

/// <inheritdoc/>
public override IsolationLevel WriteIsolationLevel { get; set; } = IsolationLevel.Unspecified;

protected override Config InternalDefaultConfig => Default;

protected override StringBuilder Build(StringBuilder sb)
Expand Down
13 changes: 13 additions & 0 deletions src/Akka.Persistence.SqlServer.Hosting/SqlServerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Data;
using System.Text;
using Akka.Configuration;
using Akka.Hosting;
Expand Down Expand Up @@ -104,6 +105,12 @@ public SqlServerJournalOptions(bool isDefaultPlugin, string identifier = "sql-se
/// </summary>
public TimeSpan QueryRefreshInterval { get; set; } = TimeSpan.FromSeconds(3);

/// <inheritdoc/>
public override IsolationLevel ReadIsolationLevel { get; set; } = IsolationLevel.Unspecified;

/// <inheritdoc/>
public override IsolationLevel WriteIsolationLevel { get; set; } = IsolationLevel.Unspecified;

protected override Config InternalDefaultConfig => Default;

protected override StringBuilder Build(StringBuilder sb)
Expand Down Expand Up @@ -187,6 +194,12 @@ public SqlServerSnapshotOptions(bool isDefaultPlugin, string identifier = "sql-s
/// </summary>
public bool UseConstantParameterSize { get; set; } = false;

/// <inheritdoc/>
public override IsolationLevel ReadIsolationLevel { get; set; } = IsolationLevel.Unspecified;

/// <inheritdoc/>
public override IsolationLevel WriteIsolationLevel { get; set; } = IsolationLevel.Unspecified;

protected override Config InternalDefaultConfig => Default;

protected override StringBuilder Build(StringBuilder sb)
Expand Down

0 comments on commit aeba095

Please sign in to comment.