事务字典

本文关键字:字典 事务 | 更新日期: 2023-09-27 18:29:53

我的应用程序中有一个IDictionary<TKey, IList<TValue>>。用户有如下请求:

我想取出:TKey=5的n个值和TKey=3的m个值。

但是,只有当所有指定的元素都存在时,才应进行删除。如果字典将具有TKey=5的n+3个值,但是只有TKey=3的m-1个值,则不应移除元素。

保证这种交易行为的最佳方式是什么?您会锁定整个字典,然后检查是否所有内容都存在,如果所有指定的查询都满足,则删除元素吗?

有没有什么方法可以使字典具有事务性?类似于:

using(var tx = new TransactionScope())
{
  foreach(var query in queries)
    // try to remove elements of query -> exception if not possible -> all others are back in place
  tx.Commit(); // ok, all queries fulfilled, commit now
}

还是最好为字典编写一个包装类,该类具有线程安全的方法TakeFromDictionary(IEnumerable<Query> queriesWhichMustBeFulfilled)

最佳做法是什么?

事务字典

Juval Lowy实现了对对象的事务性支持。他在MSDN的这篇文章中描述了自己的工作:http://msdn.microsoft.com/en-us/magazine/cc163688.aspx在他与文章一起提供的代码示例中,包含了TransactionalDictionary<T,K>
var dictionary = new TransactionalDictionary<int, string>();
dictionary.Add(1, "A");
// #1: committed transaction
using (var scope = new TransactionScope())
{
    dictionary.Add(2, "B");
    dictionary.Add(3, "C");
    dictionary.Add(4, "D");
    scope.Complete();
}
Debug.Assert(dictionary[3] == "C");
// #2: uncommitted transaction
using (var scope = new TransactionScope())
{
  dictionary[1] = "Z";
  // transaction is not completed -> rollback to initial state 
  //scope.Complete();
}
Debug.Assert(dictionary[1] == "A");

我将创建一个包装器,并在包装器的公共方法中处理锁定。

如果以后您的需求变得复杂,这也可以让您更换字典。它在一个地方实现锁定,而调用者不必担心

此外,在字典中有一个通用列表变得很难阅读(new Dictionary<String, IList<Int32>>())-这可能表明字典过载:-)