我不知道如何使用事务性数据库实现用户友好界面的撤销属性。
一方面,用户具有多级(无限)撤销的可能性是可取的,因为答案中提到了这里。在这个问题上可能有帮助的模式是纪念品或命令。
然而,使用包含触发器、不断增长的序列号和不可逆转的过程的复杂数据库,很难想象撤销操作在事务边界以外的不同点上如何工作。换句话说,撤销到最后一次提交的事务只是回滚的时候,但是怎么可能回到不同的时刻呢?
UPDATE (基于到目前为止的答案):当修改已经提交时,我不一定希望撤销工作,我将关注一个具有打开事务的正在运行的应用程序。每当用户单击保存时,它就意味着提交,但在保存之前--在同一事务期间--撤消应该有效。我知道,使用数据库作为持久层只是一个实现细节,用户不应该去理会它。但是,如果我们认为“数据库中撤消的想法和GUI中的撤销是根本不同的事情”,并且我们没有在数据库中使用撤销,那么无限的撤销只是一个时髦的词。我知道“回滚是.不是用户撤销”。
那么,如果在同一事务中发生“任何更改的结果”,那么如何实现客户级撤销呢?
发布于 2009-01-13 10:28:45
在数据库和GUI中撤销的想法是根本不同的;GUI将是一个单一的用户应用程序,与其他组件的交互程度较低;数据库是一个多用户应用程序,其中的更改可以作为任何更改的结果产生级联效应。
要做的事情是允许用户尝试并将先前的状态作为一个新事务应用,该事务可能工作,也可能不工作;或者,在提交之后不使用undos (类似于在保存后没有取消拒绝服务,这在许多应用程序中都是一个选项)。
发布于 2009-01-13 10:24:18
一些(全部?)DBMS支持保存点,允许部分回滚:
savepoint s1;
insert into mytable (id) values (1);
savepoint s2;
insert into mytable (id) values (2);
savepoint s3;
insert into mytable (id) values (3);
rollback to s2;
commit;在上面的例子中,只剩下第一个插入,其他两个就会取消。
我不认为在提交之后尝试撤销通常是不切实际的,因为您给出的原因*可能还有其他原因。如果它在某些场景中是必要的,那么您必须构建大量的代码来完成它,并考虑到触发器的影响等等。
发布于 2009-01-13 10:35:10
我们在数据库中开发了这种可能性,方法是跟踪应用于数据的所有事务(并不是所有事务,只有不到3个月的事务)。基本的想法是能够看到谁做了什么和什么时候。由GUID唯一标识的每个数据库记录,然后可视为一个INSERT、多个更新语句和最后一个DELETE语句的结果。由于我们跟踪所有这些SQL语句,而且插入是全局插入( INSERT语句中保留了所有字段值的跟踪),因此可以:
对这些功能的访问仅限于数据库管理器,因为其他用户不允许在业务规则之外进行任何数据更新(例如:一旦供应商同意采购订单,在采购订单行上的“撤销”意味着什么?)说实话,我们很少使用这个选项(一年几次?)
https://stackoverflow.com/questions/438510
复制相似问题