具有自定义sqlconnection的NServicebus处理程序
我有一个NServiceBus处理程序,可以创建新的sql连接和新的sql命令 但是,在整个过程完成之前,执行的命令不会提交到数据库 这就像在处理程序本身中有一个隐藏的sql事务 我将代码移动到一个自定义控制台应用程序中,没有使用nservicebus,sql命令立即执行并保存。与nservicebus不同,nservicebus直到处理程序结束时才保存。找到了解决方案具有自定义sqlconnection的NServicebus处理程序,nservicebus,sqlconnection,sqlcommand,Nservicebus,Sqlconnection,Sqlcommand,我有一个NServiceBus处理程序,可以创建新的sql连接和新的sql命令 但是,在整个过程完成之前,执行的命令不会提交到数据库 这就像在处理程序本身中有一个隐藏的sql事务 我将代码移动到一个自定义控制台应用程序中,没有使用nservicebus,sql命令立即执行并保存。与nservicebus不同,nservicebus直到处理程序结束时才保存。找到了解决方案 在我的连接字符串中,我必须添加Enlist=False实际上,每个处理程序都包装在一个事务中,默认事务保证依赖于DTC。这是故
在我的连接字符串中,我必须添加Enlist=False实际上,每个处理程序都包装在一个事务中,默认事务保证依赖于DTC。这是故意的:) 如果禁用它,则可能会收到重复的消息或丢失一些数据,因此必须小心操作。您可以使用端点配置API禁用事务,而不是使用连接字符串中的选项
在这里,您可以找到有关配置和可用保证的更多信息。正如@wlabaj Setting englist=False所述,将确实确保在处理程序中打开的事务与传输用于接收/发送消息的事务不同 然而,需要注意的是,它改变了消息处理语义。默认情况下,使用DTC时,处理程序中的接收/发送和任何事务操作都将以原子方式提交/回滚。如果ENSTEL=False,则情况并非如此,因此可能会为同一消息提交多个处理程序事务。考虑下面的场景作为可能发生的示例情况:
- 收到消息(开始传输事务)
- 消息已在处理程序内成功处理(处理程序事务已成功提交)
- 传输事务失败,消息被移回输入队列
- 第二次收到消息
- 消息已在处理程序内成功处理
- 创建多个端点
- 或者发送多条消息
using (new TransactionScope(TransactionScopeOption.Suppress))
{
var myMessage = new MyMessage();
bus.Send(myMessage);
}
这对V5有效,对于其他版本,最好查看文档:
登记=false
这是一种解决方法,不能用于规避特定的事务配置,Tomasz对此做了很好的解释
这可能导致数据损坏,因为在错误恢复的情况下,可以多次处理相同的消息,然后再次执行相同的数据库操作