症状
安装适用于 .NET Framework 4.6 的 2018 年 7 月.NET Framework安全和质量汇总后, Windows 7 Service Pack 1 (SP1) 、Windows Server 2008 R2 SP1 或 Windows Server 2008 SP2 上的 4.6.1、4.7、4.7.1 和 4.7.2.NET Framework满足以下条件的应用程序:
- 应用程序使用 System.Transaction.TransactionScope 类的实例,其中通过向构造函数传递 TransactionScopeAsyncFlowOption.Enabled 来启用事务流。
- 当其中一个事务范围处于活动状态时,应用程序会进行一个或多个远程调用。 在这种情况下,远程调用是在到达服务器对象之前通过透明代理传递的任何调用。 远程调用的示例包括对其他应用程序域的调用,以及通过远程处理通道进行的调用,例如 System.Runtime.Remoting.Channels 命名空间中定义的客户端通道。
- 远程调用后, System.Transactions.Transaction.Current 将返回一个 null 值,而不是在远程调用之前返回的值。
解决方法
若要解决此问题,请尝试以下任一方法:
对于启用事务流的每个事务范围,请更改应用程序,以确保在事务范围处于活动状态时运行的代码中的任何位置都没有发生远程调用。 确定事务范围是否包含任何远程调用时,请考虑以下准则:
- 对静态方法的调用从来不是远程调用。
- 对于对目标对象的实例方法的调用,仅当目标对象是透明代理时,调用才远程。
- 对于调用构造函数,仅当构造的对象是透明代理时,调用才远程。
注意始终可以使用 System.Runtime.Remoting.RemotingServices.IsTransparentProxy 方法检查对象是否为透明代理。
通过删除 TransactionScopeAsyncFlowOption.Enabled 构造函数参数来禁用事务流。
警告
如果在事务范围处于活动状态时执行任何“await”操作,则此解决方法可能会导致其他错误。
Transaction.Current 属性不会自动序列化为远程调用。 它必须作为参数传递。 如果远程调用未将事务作为参数传递,并且未在远程调用期间对客户端进行回调,则可以在使用 TransactionScopeOptions.Suppress 选项的新 TransactionScope 对象中创建远程调用。 在此禁止处理事务范围内, Transaction.Current 属性具有 null 值。
状态
我们了解此问题,目前正在制定解决方案。