마크의 대답은 작동하지만 제 경우에는 상당한 양의 코드가 부풀어 오릅니다 (그리고 이런 식으로하는 것을 잊어 버리기 쉽습니다). 따라서 패턴을 적용하는 추상화를 생각해 냈습니다.
public static class RedisExtensions
{
public static async Task TransactAsync(this IDatabase db, Action<RedisCommandQueue> addCommands)
{
var tran = db.CreateTransaction();
var q = new RedisCommandQueue(tran);
addCommands(q);
if (await tran.ExecuteAsync())
await q.CompleteAsync();
}
}
public class RedisCommandQueue
{
private readonly ITransaction _tran;
private readonly IList<Task> _tasks = new List<Task>();
public RedisCommandQueue Enqueue(Func<ITransaction, Task> cmd)
{
_tasks.Add(cmd(_tran));
return this;
}
internal RedisCommandQueue(ITransaction tran) => _tran = tran;
internal Task CompleteAsync() => Task.WhenAll(_tasks);
}
한 가지주의가 : 이것은 어떤의 결과에서 얻을 수있는 쉬운 방법을 제공하지 않습니다 여기에
await db.TransactAsync(commands => commands
.Enqueue(tran => tran.SomeCommandAsync(...))
.Enqueue(tran => tran.SomeCommandAsync(...))
.Enqueue(tran => tran.SomeCommandAsync(...)));
이 구현의 : 여기
당신이 그것을 사용하는 방법 명령. 내 경우에는 (그리고 OP의) 괜찮습니다. 저는 항상 일련의 글쓰기를 위해 트랜잭션을 사용하고 있습니다. 나는이 코드가 내 코드를 잘라내는 데 정말로 도움이된다는 것을 발견했다. 을 Enqueue
(작업을 반환해야 함)에만 노출시킴으로써 나는 그 때 해당 명령을 사용하지 말아야한다는 것을 "잊어 버릴"가능성이 적다. 나는 그들을 부른다.
내가 아직 사용할 수 없다는 의미는 여기에 "대기 중"이라고 표시되어 있습니다. http://redis.io/topics/transactions –