最近用ASP.NET做的CRM系统,BLL采用了TransactionScope来处理事务。因此,引发了一些关于TransactionScope的错误,所以在此总结一下错误类型和解决办法。
异常一、
1、异常信息如下:
异常信息为: 已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。
---- Stack Trace ----
at System.Transactions.Oletx.OletxTransactionManager.ProxyException(COMException comException)
(dll file): Native Code offset:184041
at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)
(dll file): Native Code offset:293
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
(dll file): Native Code offset:78
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
(dll file): Native Code offset:177
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
(dll file): Native Code offset:15
at System.Transactions.Transaction.Promote()
(dll file): Native Code offset:61
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)
(dll file): Native Code offset:46
at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
(dll file): Native Code offset:193
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
(dll file): Native Code offset:35
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
(dll file): Native Code offset:450
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
(dll file): Native Code offset:4846418
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
(dll file): Native Code offset:4846477
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
(dll file): Native Code offset:33
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
(dll file): Native Code offset:1286
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
(dll file): Native Code offset:65
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
(dll file): Native Code offset:117
at System.Data.SqlClient.SqlConnection.Open()
(dll file): Native Code offset:122
2、原因分析:
这个异常的原因是因为MSDTC设置不正确引起的。
3、解决办法:
3.1 检查防火墙
如果防火墙是关的,那就不用再设置了。如果防火墙是开的,那么确保msdtc.exe是在它的例外里,一般这个程序是在C:\Windows\System32 \msdtc.exe这个角落。有时候你会发现在防火墙的例外里添加了msdtc,还是不行,那有可能是跟一个端口有关系,即135端口,这是个RPC端口,在出错的时候,可以尝试将该端口也添加到防火墙的例外里。
3.2 数据库打补丁
如果数据库服务器是sql2000,那么确保已经打了sp4补丁。
如果数据库是sql2005,那么最好把sq2 补丁打上。
3.3 “管理工具”-“组件服务”-“计算机”-“我的电脑”,右键“我的电脑”,选择“属性”-“MSDTC”-“安全配置”,参照如下设置:
异常二、
1、异常信息如下:
异常信息为: 拒绝访问。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))。
---- Stack Trace ----
at System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(String nodeName, Guid resourceManagerIdentifier, IntPtr managedIdentifier, Boolean& nodeNameMatches, UInt32& whereaboutsSize, CoTaskMemHandle& whereaboutsBuffer, IResourceManagerShim& resourceManagerShim)
(dll file): Native Code offset:0
at System.Transactions.Oletx.DtcTransactionManager.Initialize()
(dll file): Native Code offset:178
at System.Transactions.Oletx.DtcTransactionManager.get_ProxyShimFactory()
(dll file): Native Code offset:71
at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)
(dll file): Native Code offset:180
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
(dll file): Native Code offset:84
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
(dll file): Native Code offset:190
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
(dll file): Native Code offset:18
at System.Transactions.Transaction.Promote()
(dll file): Native Code offset:69
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)
(dll file): Native Code offset:46
at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
(dll file): Native Code offset:193
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
(dll file): Native Code offset:20
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
(dll file): Native Code offset:463
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
(dll file): Native Code offset:133
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
(dll file): Native Code offset:5004909
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
(dll file): Native Code offset:36
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
(dll file): Native Code offset:1211
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
(dll file): Native Code offset:108
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
(dll file): Native Code offset:126
at System.Data.SqlClient.SqlConnection.Open()
(dll file): Native Code offset:125
at FengYun.FYCRM.DBUtility.DbHelperSQL.PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, String cmdText, SqlParameter[] cmdParms)
(dll file): Native Code offset:92
at FengYun.FYCRM.DBUtility.DbHelperSQL.ExecuteSql(String SQLString, SqlParameter[] cmdParms)
(dll file): Native Code offset:164
at FengYun.FYCRM.DAL.RoleOfUserDAL.Add(RoleOfUserInfo model)
(dll file): Native Code offset:1191
at FengYun.FYCRM.BLL.UserInfoBLL.Add(UserInfo model)
(dll file): Native Code offset:791
at FengYun.FYCRM.WebUI.SystemManager.UserAdd.btnSave_Click(Object sender, EventArgs e)
(dll file): Native Code offset:3159
2、原因分析:
首先, 通过上述StackTrace可以确认,问题还是出在DTC。
通过一些关键字Google了一下,原来这个问题是因为MSDTC对Authenticated Users的权限设定成(A;;CR;;;AU),而它正确地设定应该是(A;;CCLCSWRPLOCRRC;;;AU),权限解释可以参照ACE Strings。
3、解决办法:
3.1 如何查看和设定MSDTC的权限呢,首先,在DOS窗口键入“sc sdshow msdtc”,查询MSDTC现在的权限设置,如下图:
3.2 从上图可以看出,这台服务器确实将Authenticated Users的权限设定成(A;;CR;;;AU),我们只需要将(A;;CR;;;AU)修改为(A;;CCLCSWRPLOCRRC;;;AU),就可以解决问题,如下图:
3.3 DOS窗口下,“IISRESET”重启IIS。