Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 事务队列的数据结构_.net_Algorithm_Data Structures_Transactions_Queue - Fatal编程技术网

.net 事务队列的数据结构

.net 事务队列的数据结构,.net,algorithm,data-structures,transactions,queue,.net,Algorithm,Data Structures,Transactions,Queue,对于事务队列,是否有比使用列表更合适/更有效的数据结构。我试过使用Queues和Stacks,但两者都不符合要求 我已经在下面详细地概述了我的问题,并举例说明了为什么我现在会得到一个列表。任何关于替代数据结构的建议(优选但不限于那些在.Net BCL中实现的数据结构)都值得赞赏 问题 维护一个包含Insert()/Delete()操作的事务队列,当用户调用Commit()方法或调用Rollback()方法时,这些操作将保留到任意备份存储中 必须对受影响对象的内存中状态执行操作,因为后续操作可能依

对于事务队列,是否有比使用
列表
更合适/更有效的数据结构。我试过使用
Queue
s和
Stack
s,但两者都不符合要求

我已经在下面详细地概述了我的问题,并举例说明了为什么我现在会得到一个
列表。任何关于替代数据结构的建议(优选但不限于那些在.Net BCL中实现的数据结构)都值得赞赏

问题 维护一个包含
Insert()
/
Delete()
操作的事务队列,当用户调用
Commit()
方法或调用
Rollback()
方法时,这些操作将保留到任意备份存储中

必须对受影响对象的内存中状态执行操作,因为后续操作可能依赖于以前操作创建的对象的状态

例1 我有一个对象
obj
,它以空集合开始。用户插入一个项目
i
,然后将其删除

然后调用
Rollback()
。给定队列的以下数据结构,回滚时会发生以下情况:

  • 队列-
    obj.Delete(i)
    obj.Insert(i)
    → 不正确,因为在回滚后,
    obj
    应保持为空
  • 堆栈-
    obj.Insert(i)
    obj.Delete(i)
    → 正确,因为
    obj
    保持为空
  • 列表(反向遍历)
    obj.Insert(i)
    obj.Delete(i)
    → 正确,因为
    obj
    保持为空
如果他们调用
Commit()
,则会发生以下情况:

  • 队列-
    obj.Insert(i)
    obj.Delete(i)
    → 正确,因为
    obj
    保持为空
  • 堆栈-
    obj.Delete(i)
    obj.Insert(i)
    → 不正确,因为
    obj
    不是空的
  • 列表(正向遍历)
    obj.Insert(i)
    obj.Delete(i)
    → 正确,因为
    obj
    保持为空
因此,在本例中,队列适用于
Commit()
,但不适用于
Rollback()
Stack
显示相反的行为,两者都不正确。唯一的
列表
显示了正确的行为,不过请注意,对于提交,我们正向遍历列表,而对于回滚,我们反向遍历列表

例2

现在,再考虑一个对象<代码> Obj>代码>,这个时间从单个项目<代码> i>代码>开始。 这一次,操作顺序是删除

i
,然后插入
i

如果调用
Rollback()
,则会发生以下情况:

  • 队列-
    obj.Insert(i)
    obj.Delete(i)
    → 不正确,因为
    obj
    最终为空
  • 堆栈-
    obj.Delete(i)
    obj.Insert(i)
    → 正确,因为
    obj
    仍然包含单个项目
    i
  • 列表(反向遍历)
    obj.Delete(i)
    obj.Insert(i)
    → 正确,因为
    obj
    仍然包含单个项目
    i
如果改为调用
Commit()
,则会发生以下情况:

  • 队列-
    obj.Delete(i)
    obj.Insert(i)
    → 正确,因为
    obj
    仍然包含单个项目
    i
  • 堆栈-
    obj.Insert(i)
    obj.Delete(i)
    → 不正确,因为
    obj
    最终为空
  • 列表(正向遍历)
obj.Delete(i),
obj.Insert(i)
→ 正确,因为
obj
仍然包含单个项目
i
与前面的示例一样,在这两种情况下,仅使用
List
是正确的,但我们必须根据提交还是回滚,在不同的方向遍历它

底线
虽然使用
列表本身并不低效,但我只是想知道是否有更合适的数据结构更适合我的问题?

从技术上讲,您可以使用
链接列表。它就像一个
队列
+
堆栈
:您可以从头部和尾部添加和删除,在这两种情况下,它都是
O(1)
(但通常比
列表
慢,原因与内存位置有关,并且需要为每个元素的添加分配内存)

(请不要杀了我,因为我说过
链接列表
就像
队列
+
堆栈
…我知道区别…我的意思是它可以同时以两种方式使用。)

< P> >我补充说,如果你考虑<代码>回滚一个“异常”(稀有),那么你可以使用<代码>队列< /> >,并且当你有一个<代码>回滚< /代码>时,<代码>反转< /代码>使用LINQ输出<代码>队列 >。作为一个“例外”,它可能会慢一些(而且您甚至不需要LINQ…您可以执行
ToArray()
并以相反的顺序遍历数组)