BaseLib.Core.MySql 3.1.3

dotnet add package BaseLib.Core.MySql --version 3.1.3
                    
NuGet\Install-Package BaseLib.Core.MySql -Version 3.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BaseLib.Core.MySql" Version="3.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BaseLib.Core.MySql" Version="3.1.3" />
                    
Directory.Packages.props
<PackageReference Include="BaseLib.Core.MySql" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BaseLib.Core.MySql --version 3.1.3
                    
#r "nuget: BaseLib.Core.MySql, 3.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BaseLib.Core.MySql@3.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BaseLib.Core.MySql&version=3.1.3
                    
Install as a Cake Addin
#tool nuget:?package=BaseLib.Core.MySql&version=3.1.3
                    
Install as a Cake Tool

BaseLib.Core.MySql

Overview

Contains concrete implementations of the interfaces from BaseLib.Core for MySQL.

Services

JournalEntryWriter

JournalEntryWriter implements IJournalEntryWriter to persist service execution records in a relational JOURNAL table.

On each service run, two writes occur:

  1. Started — an INSERT when the service begins.
  2. Finished — an UPDATE when the service completes (falls back to INSERT if the started record is missing).

Best practice: Store only the JournalEntry (metadata) in the relational database. Request and response payloads should be stored in a secure object store (e.g. S3).

JOURNAL table schema

Run dbinstall-v1.0.0.sql (included in the source) to create the table:

CREATE TABLE IF NOT EXISTS JOURNAL (
  ID int NOT NULL AUTO_INCREMENT,
  SERVICE_NAME VARCHAR(255) DEFAULT NULL,
  STARTED_ON TIMESTAMP(6) DEFAULT NULL,
  FINISHED_ON TIMESTAMP(6) DEFAULT NULL,
  OPERATION_ID VARCHAR(255) DEFAULT NULL,
  CORRELATION_ID VARCHAR(255) DEFAULT NULL,
  SUCCEEDED BOOLEAN DEFAULT NULL,
  REASON_CODE INT DEFAULT NULL,
  REASON VARCHAR(255),
  MESSAGES TEXT,
  PRIMARY KEY (ID),
  UNIQUE KEY IX_OPERATION (OPERATION_ID),
  KEY IX_CORRELATION (CORRELATION_ID),
  KEY IX_SERVICE_DATES (STARTED_ON,SERVICE_NAME)
)
Configuration
// Register per-request (transient) since MySqlConnection is not thread-safe
services.AddTransient<IJournalEntryWriter>(sp =>
{
    var connection = new MySqlConnection(connectionString);
    connection.Open();
    return new JournalEntryWriter(connection);
});

LongRunningServiceManager

LongRunningServiceManager implements ICoreLongRunningServiceManager using a MySQL LONG_RUNNING_BATCH table to track parent/child service relationships.

It reacts to three lifecycle events:

Event Action
HandleParentSuspendedAsync Inserts a parent batch record; resumes immediately if all children already finished
HandleChildrenFinishedAsync Bulk-inserts child records and updates counters; resumes the parent when all children are done
HandleParentFinishedAsync Updates the parent batch record with the final status
LONG_RUNNING_BATCH table schema
CREATE TABLE IF NOT EXISTS LONG_RUNNING_BATCH (
  ID int NOT NULL AUTO_INCREMENT,
  OPERATION_ID VARCHAR(255) NOT NULL,
  CORRELATION_ID VARCHAR(255) DEFAULT NULL,
  SERVICE_NAME VARCHAR(500) DEFAULT NULL,
  SERVICE_STATUS INT DEFAULT NULL,
  STARTED_ON TIMESTAMP(6) DEFAULT NULL,
  FINISHED_ON TIMESTAMP(6) DEFAULT NULL,
  SUCCEEDED BOOLEAN DEFAULT NULL,
  REASON_CODE INT DEFAULT NULL,
  REASON VARCHAR(255) DEFAULT NULL,
  CHILDREN_COUNT INT DEFAULT NULL,
  COMPLETED_OK INT DEFAULT NULL,
  COMPLETED_ERR INT DEFAULT NULL,
  LAST_UPDATED TIMESTAMP(6) DEFAULT NULL,
  PRIMARY KEY (ID),
  UNIQUE KEY IX_OPERATION (OPERATION_ID),
  KEY IX_CORRELATION (CORRELATION_ID)
)
Configuration
services.AddSingleton<ICoreLongRunningServiceManager>(sp =>
    new LongRunningServiceManager(
        connectionFactory: () =>
        {
            var conn = new MySqlConnection(connectionString);
            conn.Open();
            return conn;
        },
        invoker: sp.GetRequiredService<ICoreServiceFireOnly>()
    ));

Extensions

MySqlConnection extensions

Method Description
SetWaitTimeout(int timeout) Sets the MySQL session wait_timeout in seconds. Useful in long-lived connection pools to prevent silent disconnects.
GetWaitTimeout() Returns the current session wait_timeout value.
using (var conn = new MySqlConnection(connectionString))
{
    conn.Open();
    conn.SetWaitTimeout(3600); // keep connection alive for 1 hour
}

MySqlException extensions

Method Returns Description
IsTransient() bool true for transient errors (stream read failures, timeouts, deadlocks, connection failures) that are safe to retry.
IsDuplicate() bool true for duplicate key violations (safe to swallow on upsert patterns).
catch (MySqlException ex) when (ex.IsTransient())
{
    // retry logic
}

Troubleshooting

"Reading from the stream has failed" / connection drops

The MySQL server closed the connection while it was idle in the pool. Use SetWaitTimeout to align the session timeout with your application's connection pool idle timeout, or configure keep-alive pings in the connection string:

Server=...;Connection Timeout=30;Default Command Timeout=60;Connection Reset=true;

Duplicate key on JOURNAL insert

JournalEntryWriter silently ignores duplicate-key exceptions on insert (IsDuplicate() returns true). This is expected when a Started event arrives after the Finished event due to out-of-order delivery.

"max_allowed_packet" errors on bulk child insert

LongRunningServiceManager batches child records in groups of 128 rows. If you still hit packet-size limits, reduce the batch by lowering the constant or increase max_allowed_packet in your MySQL server config.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.1.3 109 4/5/2026
3.1.1 114 2/25/2026
3.1.0 271 9/8/2025
3.0.0-beta-001 229 5/7/2025
2.1.0 1,957 12/28/2023
2.0.0 555 11/7/2023
1.0.0 259 10/16/2023
1.0.0-beta-001 992 8/11/2023