我最近在WF中使用过一些基于ExternalDataExchange的通信。我的理解是,当使用长时间运行(在这种情况下,状态机)工作流时,通信是排队的,持久的和事务性的。
我正在使用SQL Persistence和一个标记为“WaitForIdle = true”的EventArgs。
我会假设当我做这样的事情时:
using(TransactionScope scope = new TransactionScope())
{
IMyEDEService service = wfRuntime.GetService<IMyEDEService>()
service.MyMethod(wfInstanceGuid, "Here's some data");
DoSomeDatabaseWork();
} //Dispose causes scope to rollback
我希望我的活动不会触发工作流程。它似乎实际上已经交付,所以这让我相信这不是交易性的。您可以看到在DoSomeDatabaseWork()中提交给数据库的数据是如何回滚的,但是工作流向前移动可能很糟糕。
任何人都可以确认这一点,如果有,您是否有一个解决方法使消息成为事务性消息?
我真正想要的是这两件事之一:
- 或 -
答案 0 :(得分:2)
这里有几个问题。首先,当您使用SQL持久性时,通知事件的工作流并让工作流发布事件是持久的和异步的,并且工作流的底层管道是事务性的......但不是您想象的方式。
如果在事件序列中某处发生可怕的事情,最终会导致工作流转换到新状态,那么工作流将恢复到尝试活动之前的状态 - 这使工作流保持一致状态因为“在州之间”是一个坏主意。
如上所述使用事务范围很好,但您必须记住事务范围实际工作的唯一时间是使用块中的类知道事务范围。
你可以做的是让你的“MyMethod”调用在try / catch块中包装。当出现问题时,你可以投票支持回滚......但是这仍然不能“取消”你的EDES上的方法。
如果你可以提供一些关于你想要在更高层次上完成什么的具体细节,那么WF可能会有一些内在的东西可能更适合你,而不是试图将交易范围搞砸到混合中。
我做了一些挖掘,发现了几个不同的地方我们被告知没有API来操作调度程序工作队列。对我们来说不幸的是,这意味着我们希望我们自己手动实现任何类型的回滚行为。
如果我更多地了解您为什么要尝试回滚通过EDES排队的工作,我可能会建议一些潜在的架构来完成您的任务,而无需重新发明轮子(交易)。
当我遇到像这样的问题看起来WF只是不支持我想要做的事情时,10次中有9次,问题是因为我要么在外面保留太多代码 / em>工作流程或试图将太多代码放入它并重构我的工作完成的地方经常修复我的问题而不需要我写新东西。