-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
794 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"folders": [ | ||
{ | ||
"path": "." | ||
} | ||
], | ||
"settings": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
all: pack | ||
|
||
pack: build | ||
mkdir -p `pwd`/packages | ||
dotnet pack -c Release `pwd`/src/Eventual2PC/ | ||
mv `pwd`/src/Eventual2PC/bin/Release/*.nupkg `pwd`/packages/ | ||
|
||
build: | ||
dotnet build -c Release `pwd`/src/Eventual2PC/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,106 @@ | ||
# Eventual2PC | ||
最终一致性二阶段提交范式,简化多聚合根之间交互事务的实现。 | ||
|
||
最终一致性二阶段提交范式,简化多聚合根之间交互事务的实现。任何基于cqrs + eda 实现多聚合根最终一致性的框架,都可使用。 | ||
|
||
## 安装 | ||
|
||
``` | ||
dotnet add package Eventual2PC | ||
``` | ||
|
||
## 范式 | ||
|
||
### 术语定义 | ||
|
||
- `Initiator`: 作为事务发起方,它是聚合根 | ||
|
||
- `Participant`: 作为事务参与方(仅被修改的聚合根,新增的,不会产生业务失败问题),它是聚合根 | ||
|
||
- `Preparation`: 事务准备,对应一个具体的业务修改动作;同一个 `Participant` 参与多个事务时,应定义多个事务准备 | ||
|
||
- `Transaction`: 2PC事务,从开始事务,到事务完成,贯穿整个事务生命周期;可以只是一个标识ID(通常使用 `TransactionStarted` 事件的ID),也可以使用代表事务的聚合根(如银行转账的转账事务聚合根) | ||
|
||
- `ProcessManager`: CQRS中的概念,作为事务相关消息路由的角色,负责响应 `DomainEvent`、`DomainException` 消息,并发送 `Command` 消息 | ||
|
||
#### Initiator 事件定义 | ||
|
||
- `TransactionStarted`: 事务已发起事件 | ||
|
||
- `PreCommitSucceedParticipantAdded`: 预提交成功的参与者已添加事件 | ||
|
||
- `PreCommitFailedParticipantAdded`: 预提交失败的参与者已添加事件 | ||
|
||
- `AllParticipantPreCommitSucceed`: 所有参与者预提交已成功事件 | ||
|
||
- `AnyParticipantPreCommitFailed`: 任意一个参与者预提交已失败事件 | ||
|
||
- `CommittedParticipantAdded`: 已提交的参与者已添加事件(Option) | ||
|
||
- `RolledbackParticipantAdded`: 已回滚的参与者已添加事件(Option) | ||
|
||
- `TransactionCompleted`: 事务已完成事件(Option),并包含是否事务已提交的状态 | ||
|
||
#### Participant 事件定义 | ||
|
||
- `PreCommitSucceed`: 预提交已成功事件 | ||
|
||
- `PreCommitFailed`: 预提交已失败事件(或领域异常消息) | ||
|
||
- `Committed`: 已提交事件 | ||
|
||
- `Rolledback`: 已回滚事件 | ||
|
||
|
||
### 规范 | ||
|
||
- 一个聚合根,可以同时扮演 `Initiator` 和 `Transaction`的角色,如银行转账事务聚合根 | ||
|
||
- 一个聚合根,可以同时扮演事务A中的 `Participant` 和事务B的 `Initiator` | ||
|
||
- 一个 `Participant`,参与多少个事务,需对应定义多少个`Preparation` | ||
|
||
- `Participant` 的聚合根实例,允许同时参与多个不同的事务;也可以通过业务代码,在 `PreCommit` 时,判断是否存在其他类型的 `Preparation` 来阻止参与多个事务 | ||
|
||
- `Initiator` 必须发布事件 `TransactionStarted`、`PreCommitSucceedParticipantAdded`、`PreCommitFailedParticipantAdded`、`AllParticipantPreCommitSucceed`、`AnyParticipantPreCommitFailed` | ||
|
||
- `Participant` 必须发布事件 `PreCommitSucceed`、`PreCommitFailed`、`Committed`、`Rolledback` | ||
|
||
- 如果需要关注 `Transaction` 是否已完成,则 `Initiator` 需要发布事件 `CommittedParticipantAdded`、`RolledbackParticipantAdded`、`TransactionCompleted` | ||
|
||
### 处理流程 | ||
|
||
- `Initiator` 发布 `TransactionStarted` 事件; | ||
|
||
- `ProcessManager` 响应 `TransactionStarted` 事件,并发送 `PreCommit` 命令; | ||
|
||
- `Participant` 接受命令 `PreCommit`,如果成功,则发布 `PreCommitSucceed` 事件;如果失败,则发布 `PreCommitFailed` 事件(或领域异常); | ||
|
||
- `ProcessManager` 响应 `PreCommitSucceed`,并发送 `AddPreCommitSucceedParticipant` 命令; | ||
|
||
- `ProcessManager` 响应 `PreCommitFailed`,并发送 `AddPreCommitFailedParticipant` 命令; | ||
|
||
- `Initiator` 接受命令 `AddPreCommitSucceedParticipant`,发布 `PreCommitSucceedParticipantAdded` 事件;如果所有 `Participant` 的 `PreCommit` 都已处理完成,则发布 `AllParticipantPreCommitSucceed` 事件; | ||
|
||
- `Initiator` 接受命令 `AddPreCommitFailedParticipant`,发布 `PreCommitFailedParticipantAdded` 事件;如果所有 `Participant` 的 `PreCommit` 都已处理完成,则发布 `AnyParticipantPreCommitFailed` 事件; | ||
|
||
- `ProcessManager` 响应 `AllParticipantPreCommitSucceed`,并发送 `Commit` 命令; | ||
|
||
- `ProcessManager` 响应 `AnyParticipantPreCommitFailed`,并发送 `Rollback` 命令; | ||
|
||
- `Participant` 接受命令 `Commit`,并发布 `Committed` 事件; | ||
|
||
- `Participant` 接受命令 `Rollback`,并发布 `Rolledback` 事件; | ||
|
||
- `ProcessManager` 响应 `Committed`,并发送 `AddCommittedParticipant` 命令; | ||
|
||
- `ProcessManager` 响应 `Rolledback`,并发送 `AddRolledbackParticipant` 命令; | ||
|
||
- `Initiator` 接受命令 `AddCommittedParticipant`,发布 `CommittedParticipantAdded` 事件;如果所有 `Participant` 的 `Commit` 都已处理完成,则发布 `TransactionCompleted` 事件; | ||
|
||
- `Initiator` 接受命令 `AddRolledbackParticipant`,发布 `RolledbackParticipantAdded` 事件;如果所有 `Participant` 的 `Rolledback` 都已处理完成,则发布 `TransactionCompleted` 事件。 | ||
|
||
## 发布历史 | ||
|
||
### 1.0.0(2020/4/25) | ||
|
||
- 初始版本 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 15 | ||
VisualStudioVersion = 15.0.26124.0 | ||
MinimumVisualStudioVersion = 15.0.26124.0 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventual2PC", "Eventual2PC\Eventual2PC.csproj", "{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Debug|x64 = Debug|x64 | ||
Debug|x86 = Debug|x86 | ||
Release|Any CPU = Release|Any CPU | ||
Release|x64 = Release|x64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|x64.ActiveCfg = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|x64.Build.0 = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|x86.ActiveCfg = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Debug|x86.Build.0 = Debug|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|x64.ActiveCfg = Release|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|x64.Build.0 = Release|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|x86.ActiveCfg = Release|Any CPU | ||
{FB832C09-5CB6-4A1D-A11D-F7E10D94E333}.Release|x86.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
26 changes: 26 additions & 0 deletions
26
src/Eventual2PC/Events/ITransactionInitiatorAllParticipantPreCommitSucceed.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 事务参与方所有预提交已成功事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorAllParticipantPreCommitSucceed<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务参与方信息 | ||
/// </summary> | ||
IEnumerable<TransactionParticipantInfo> TransactionParticipants { get; } | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/Eventual2PC/Events/ITransactionInitiatorAnyParticipantPreCommitFailed.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 事务参与方任意一个预提交已失败的事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorAnyParticipantPreCommitFailed<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 成功预提交的事务参与方信息 | ||
/// </summary> | ||
IEnumerable<TransactionParticipantInfo> PreCommitSucceedTransactionParticipants { get; } | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Eventual2PC/Events/ITransactionInitiatorCommittedParticipantAdded.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 已提交的事务参与方已添加事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorCommittedParticipantAdded<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务参与方信息 | ||
/// </summary> | ||
TransactionParticipantInfo TransactionParticipant { get; } | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Eventual2PC/Events/ITransactionInitiatorPreCommitFailedParticipantAdded.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 预提交失败的事务参与方已添加事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorPreCommitFailedParticipantAdded<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务参与方信息 | ||
/// </summary> | ||
TransactionParticipantInfo TransactionParticipant { get; } | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Eventual2PC/Events/ITransactionInitiatorPreCommitSucceedParticipantAdded.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 预提交成功的事务参与方已添加事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorPreCommitSucceedParticipantAdded<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务参与方信息 | ||
/// </summary> | ||
TransactionParticipantInfo TransactionParticipant { get; } | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Eventual2PC/Events/ITransactionInitiatorRolledbackParticipantAdded.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 已回滚的事务参与方已添加事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorRolledbackParticipantAdded<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务参与方信息 | ||
/// </summary> | ||
TransactionParticipantInfo TransactionParticipant { get; } | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Eventual2PC/Events/ITransactionInitiatorTransactionCompleted.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 事务已完成事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorTransactionCompleted<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
|
||
/// <summary> | ||
/// 事务是否成功 | ||
/// </summary> | ||
bool IsCommitSuccess { get; } | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Eventual2PC/Events/ITransactionInitiatorTransactionStarted.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 事务已开始事件接口 | ||
/// </summary> | ||
public interface ITransactionInitiatorTransactionStarted<TInitiator> | ||
where TInitiator : class, ITransactionInitiator | ||
{ | ||
/// <summary> | ||
/// 事务ID | ||
/// </summary> | ||
string TransactionId { get; } | ||
|
||
/// <summary> | ||
/// 事务类型 | ||
/// </summary> | ||
byte TransactionType { get; } | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
src/Eventual2PC/Events/ITransactionParticipantCommitted.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace Eventual2PC.Events | ||
{ | ||
/// <summary> | ||
/// 事务参与者已提交事件 | ||
/// </summary> | ||
/// <typeparam name="TParticipant"></typeparam> | ||
/// <typeparam name="TTransactionPreparation"></typeparam> | ||
public interface ITransactionParticipantCommitted<TParticipant, TTransactionPreparation> | ||
where TParticipant : class, ITransactionParticipant | ||
where TTransactionPreparation : class, ITransactionPreparation | ||
{ | ||
/// <summary> | ||
/// 事务准备 | ||
/// </summary> | ||
TTransactionPreparation TransactionPreparation { get; } | ||
} | ||
} |
Oops, something went wrong.