Skip to content

Commit

Permalink
Merge pull request #12 from SiroccoHub/feature/update-1.1.0
Browse files Browse the repository at this point in the history
update 1.1.0
  • Loading branch information
arichika authored Jun 2, 2020
2 parents 3fe99ea + a476e9d commit ed226a1
Show file tree
Hide file tree
Showing 7 changed files with 495 additions and 301 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,19 @@ Simply installing the following Nuget package:

### History

#### v0.1.0
+ First release.

#### v0.2.0
+ Breaking chagne: Forgetting to vote is abnormal and throws an `InvalidOperationException()`.
#### v1.1.0
+ Fix invalid log comment.
+ Fix the `first transaction`'s behavior.
+ The first `RequresNew` Tx has the *own scope*, The first `Requred` Tx has the *manager scope*.

#### v1.0.0
+ Change Dependencies.
+ `Microsoft.Data.SqlClient` is used instead of `System.Data.SqlClient`
+ https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#SqlClient
+ Update Dependencies.

#### v0.2.0
+ Breaking chagne: Forgetting to vote is abnormal and throws an `InvalidOperationException()`.

#### v0.1.0
+ First release.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<AssemblyName>OneWorldDbClient.SqlServer</AssemblyName>
<PackageId>OneWorldDbClient.SqlServer</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<Version>1.1.0</Version>

<Authors>@arichika (arichika.taniguchi) / team sirocco, LLC.</Authors>
<Title>OneWorldDbClient.SqlServer</Title>
Expand Down
491 changes: 330 additions & 161 deletions src/OneWorldDbClient.Tests/OneWorldDbClientMonoDbCtxTests.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/OneWorldDbClient/OneWorldDbClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<AssemblyName>OneWorldDbClient</AssemblyName>
<PackageId>OneWorldDbClient</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<Version>1.1.0</Version>

<Authors>@arichika (arichika.taniguchi) / team sirocco, LLC.</Authors>
<Title>OneWorldDbClient</Title>
Expand Down
98 changes: 53 additions & 45 deletions src/OneWorldDbClient/OneWorldDbClientManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace OneWorldDbClient
{
public class OneWorldDbClientManager<TDbContext> : IDisposable where TDbContext : DbContext
public sealed class OneWorldDbClientManager<TDbContext> : IDisposable where TDbContext : DbContext
{
private readonly string _connectionString;

Expand Down Expand Up @@ -49,7 +49,7 @@ public void Dispose()


/// <summary>
/// トランザクションが存在すれば参加し、なければ新規に作成します。
/// トランザクションが存在すれば参加し、なければ新規に作成します。
/// </summary>
/// <param name="isolationLevel">null の場合、最初のトランザクションであれば IsolationLevel.ReadCommitted に、参加する場合は上位に依存します。</param>
/// <param name="memberName"></param>
Expand All @@ -65,26 +65,28 @@ public async Task<OneWorldDbTransactionScope<TDbContext>> BeginTranRequiredAsync
// current tx not found. create new tx.
if (!_publishedTransactionStack.TryPeek(out var latestTransactionId))
return await BeginTranRequiresNewInternalAsync(
isolationLevel,
memberName,
sourceFilePath,
sourceLineNumber);
isSuperRootTx: true,
isolationLevel: isolationLevel,
memberName: memberName,
sourceFilePath: sourceFilePath,
sourceLineNumber: sourceLineNumber);

// current tx found.
if (!_transactions.TryGetValue(latestTransactionId, out var transaction))
throw new InvalidProgramException($"lost transaction {latestTransactionId}");

_logger.LogInformation($" Required:TransactionNumber=`{transaction.TransactionNumber}`/TransactionId=`{transaction.TransactionId}`/IsolationLevel=`{transaction.IsolationLevel}`");

if (!isolationLevel.HasValue || isolationLevel == transaction.IsolationLevel)
return await transaction.CreateTransactionScopeAsync(memberName, sourceFilePath, sourceLineNumber);

throw new InvalidOperationException(
$"{nameof(isolationLevel)} で指定されたトランザクション {isolationLevel} は、" +
$"既に存在するトランザクションレベル {transaction.IsolationLevel} と相違しています。");
$"{nameof(isolationLevel)} で指定されたトランザクション {isolationLevel} は、既に存在するトランザクションレベル {transaction.IsolationLevel} と相違しています。");
}


/// <summary>
/// トランザクションを新規に開始します。
/// トランザクションを新規に開始します。
/// </summary>
/// <param name="isolationLevel">null の場合、最初のトランザクションであれば IsolationLevel.ReadCommitted に、参加する場合は上位に依存します。</param>
/// <param name="memberName"></param>
Expand All @@ -98,35 +100,42 @@ public async Task<OneWorldDbTransactionScope<TDbContext>> BeginTranRequiresNewAs
[CallerLineNumber] int sourceLineNumber = 0)
{
return await BeginTranRequiresNewInternalAsync(
isolationLevel,
memberName,
sourceFilePath,
sourceLineNumber);
isSuperRootTx: false,
isolationLevel: isolationLevel,
memberName: memberName,
sourceFilePath: sourceFilePath,
sourceLineNumber: sourceLineNumber);
}


/// <summary>
/// トランザクションを新規に開始する内部メソッド
/// トランザクションを新規に開始する内部メソッド
/// </summary>
/// <param name="isSuperRootTx"></param>
/// <param name="isolationLevel"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
/// <returns></returns>
private async Task<OneWorldDbTransactionScope<TDbContext>> BeginTranRequiresNewInternalAsync(
bool isSuperRootTx,
IsolationLevel? isolationLevel = null,
string memberName = "",
string sourceFilePath = "",
int sourceLineNumber = 0)
{
var firstTran = OneWorldDbTransaction<TDbContext>.CreateOneWorldDbTransaction(
Guid.NewGuid(),
_transactions.Count,
_dbConnectionFactory.Invoke(_connectionString),
isolationLevel ?? IsolationLevel.ReadCommitted,
this,
_dbContextFactory,
_loggerTx);
var transactionNumber = isSuperRootTx ? -1 : _transactions.Count;
var firstTran =
OneWorldDbTransaction<TDbContext>.CreateOneWorldDbTransaction(
transactionId: Guid.NewGuid(),
transactionNumber: transactionNumber,
dbConnection: _dbConnectionFactory.Invoke(_connectionString),
isolationLevel: isolationLevel ?? IsolationLevel.ReadCommitted,
oneWorldDbClientManager: this,
dbContextFactory: _dbContextFactory,
logger: _loggerTx);

_logger.LogInformation($" RequiresNew:isSuperRootTx=`{isSuperRootTx}`,TransactionNumber=`{firstTran.TransactionNumber}`/TransactionId=`{firstTran.TransactionId}`/IsolationLevel=`{firstTran.IsolationLevel}`");

if (!_transactions.TryAdd(firstTran.TransactionId, firstTran))
throw new InvalidProgramException($"duplicate transaction id {firstTran.TransactionId}");
Expand All @@ -137,9 +146,8 @@ private async Task<OneWorldDbTransactionScope<TDbContext>> BeginTranRequiresNewI
}


public void SubTransactionFinalize(Guid endedSubTransactionId)
public void TransactionFinalize(Guid endedSubTransactionId)
{
// strictly, strictly, strictly...
lock (_publishedTransactionStack)
{
if (_publishedTransactionStack.TryPeek(out var latestTransactionId))
Expand All @@ -150,13 +158,13 @@ public void SubTransactionFinalize(Guid endedSubTransactionId)
{
if (_transactions.TryRemove(endedSubTransactionId, out var transaction))
{
_logger?.LogInformation($" sub.tx={endedSubTransactionId} Disposing.");
_logger?.LogTrace($" sub.tx={endedSubTransactionId} Disposing.");
transaction.Dispose();
_logger?.LogInformation($" sub.tx={endedSubTransactionId} Disposed and Removed.");
_logger?.LogDebug($" sub.tx={endedSubTransactionId} Disposed and Removed.");
}
else
{
_logger?.LogInformation($" sub.tx={endedSubTransactionId} Already Removed.");
_logger?.LogDebug($" sub.tx={endedSubTransactionId} Already Removed.");
}
}
else
Expand All @@ -179,30 +187,30 @@ public void SubTransactionFinalize(Guid endedSubTransactionId)
}


protected virtual void Dispose(bool disposing)
private void Dispose(bool disposing)
{
if (disposing)
if (!disposing)
return;

_logger?.LogDebug($" Dispose {nameof(OneWorldDbClientManager<TDbContext>)} start.");

while (_publishedTransactionStack.Count > 0)
{
_logger?.LogInformation($"Dispose {nameof(OneWorldDbClientManager<TDbContext>)} start.");
_publishedTransactionStack.TryPop(out var latestTransactionId);

while (_publishedTransactionStack.Count > 0)
if (_transactions.TryRemove(latestTransactionId, out var transaction))
{
_publishedTransactionStack.TryPop(out var latestTransactionId);

if (_transactions.TryRemove(latestTransactionId, out var transaction))
{
_logger?.LogInformation($" tx={latestTransactionId} Disposing.");
transaction.Dispose();
_logger?.LogInformation($" tx={latestTransactionId} Disposed and Removed.");
}
else
{
_logger?.LogInformation($" tx={latestTransactionId} Already Removed.");
}
_logger?.LogDebug($" tx={latestTransactionId} Disposing.");
transaction.Dispose();
_logger?.LogDebug($" tx={latestTransactionId} Disposed and Removed.");
}
else
{
_logger?.LogDebug($" tx={latestTransactionId} Already Removed.");
}

_logger?.LogInformation($"Dispose {nameof(OneWorldDbClientManager<TDbContext>)} ended.");
}

_logger?.LogInformation($" Dispose {nameof(OneWorldDbClientManager<TDbContext>)} ended.");
}


Expand Down
Loading

0 comments on commit ed226a1

Please sign in to comment.