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