오늘 아침에 컴퓨터를 부팅하면 작업중인 프로젝트의 정확한 문제가 발생했습니다. 나는 다음과 같은 디자인으로 이어지는 몇 가지 아이디어를 가지고 있으며, 코멘트는 그 이상이 될 것입니다. 불행하게도 Josh가 제안한 디자인은 불가능합니다. 원격 SQL 서버를 사용해야하고 의존하는 Distribute Transaction Coordinator 서비스를 사용할 수 없기 때문입니다.
내 솔루션은 기존 코드에 대한 몇 가지 간단한 변경 사항을 기반으로합니다.
첫째, 내 모든 저장소는 간단한 마커 인터페이스 구현이 있습니다
/// <summary>
/// Provides methods to enable transaction support.
/// </summary>
public interface IHasTransactions : IRepository
{
/// <summary>
/// Initiates a transaction scope.
/// </summary>
void BeginTransaction();
/// <summary>
/// Executes the transaction.
/// </summary>
void CommitTransaction();
}
아이디어는에서이다 : 두 번째
/// <summary>
/// A base interface for all repositories to implement.
/// </summary>
public interface IRepository
{ }
을, 내 모든 거래 활성화 저장소는 다음과 같은 인터페이스를 구현하자 내 모든 저장소이 인터페이스를 구현하고 실제 공급자에 따라 트랜잭션을 직접 도입하는 코드를 추가합니다 (가짜 저장소의 경우 커밋시 실행되는 대리자 목록을 만들었습니다). LINQ는 SQL하는 것이 같은 구현을 쉽게 만들 수있을 것입니다 : 물론
#region IHasTransactions Members
public void BeginTransaction()
{
_db.Transaction = _db.Connection.BeginTransaction();
}
public void CommitTransaction()
{
_db.Transaction.Commit();
}
#endregion
이를 새 저장소 클래스가 각 스레드 생성되어 있어야하지만,이 내 프로젝트에 대한 합리적이다.
저장소가 IHasTransactions
인 경우 저장소를 사용하는 각 방법은 BeginTransaction()
및 EndTransaction()
을 호출해야합니다. 이 전화를 더 쉽게 사용하기 위해 다음 확장명을 제안했습니다.
/// <summary>
/// Extensions for spawning and subsequently executing a transaction.
/// </summary>
public static class TransactionExtensions
{
/// <summary>
/// Begins a transaction if the repository implements <see cref="IHasTransactions"/>.
/// </summary>
/// <param name="repository"></param>
public static void BeginTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.BeginTransaction();
}
}
public static void CommitTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.CommitTransaction();
}
}
}
댓글 감사합니다.
나는 이것이 DDD의 정신에서 해결책이라고 생각하지 않는다. 기본적으로 도메인 모델 작업을 수행하는 트랜잭션 스크립트를 만들었습니다. 서비스는 예를 들어 고객 상태를 변경하면 안됩니다. –
코드의 일부가이 비즈니스 규칙을 처리해야합니다.이 수준 또는 상위 수준에서 트랜잭션을 처리하기 위해 로컬 트랜잭션 또는 분산 트랜잭션을 허용하는 단일 TransactionScope 내에서 변경을 수행하고 있었습니까?주문이있을 때마다 고객을 업데이트하라는 비즈니스 규칙이 있으면 모든 주문이 여기에 적용되므로이를 처리하는 것이 좋습니다. – JoshBerke