MSDTC - 基礎となるトランザクションマネージャとの通信は、(上のファイアウォールのオープン、MSDTCがネットワークアクセスを)失敗しました
-
21-09-2019 - |
質問
私はASP.NET Webフォームのシステムの問題を抱えている。
それは我々のテストサーバー上で働いていたが、今、私たちはDMZ内にあり、SQLサーバーがその外のそれをサーバのライブ1を入れている(まだ私達のネットワークにかかわらず - 異なるサブネットが)
私はそれが問題だったかどうかを確認するために、ファイアウォール完全にこれらの2つのボックスの間に開きがあり、我々がしようとすると「のTransactionScope」を使用するたびに、それはまだ、「失敗した根本的なトランザクションマネージャとの通信」エラーメッセージを表示します。私たちは、それはそれを破るだけで取引をです検索用のデータにアクセスすることができます。
我々はまた、それのpingに成功し、ファイアウォールの接続および修正をテストするためにMSDTCのpingを使用していたが、同じエラーが発生した!
私はこのエラーを解決する方法を教えてください。
私たちが今日生きて行くためのシステムを持っているとしてすべてのヘルプは素晴らしいことです。パニック:)
の編集の私は以下のようにトランザクションをより簡単なテストページを作成しているし、これはうまく動作します。ファイアウォールとDMZにライブボックスを使用するときにこの種のエラーの原因とそうであれば、ネストされたトランザクションは、なぜこれが唯一の問題を引き起こすだろうか?
AuditRepository auditRepository = new AuditRepository();
try
{
using (TransactionScope scope = new TransactionScope())
{
auditRepository.Add(DateTime.Now, 1, "TEST-TRANSACTIONS#1", 1);
auditRepository.Save();
auditRepository.Add(DateTime.Now, 1, "TEST-TRANSACTIONS#2", 1);
auditRepository.Save();
scope.Complete();
}
}
catch (Exception ex)
{
Response.Write("Test Error For Transaction: " + ex.Message + "<br />" + ex.StackTrace);
}
この問題が発生したときに我々が取得しているerrorStackがあります。
でSystem.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[]
propagationToken) at
System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx) at
System.Transactions.Transaction.Promote() at
System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction
transaction) at System.Transactions.TransactionInterop.GetExportCookie(Transaction
transaction, Byte[] whereabouts) at
System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction
transaction, Byte[] whereAbouts) at
System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) at
System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx) at
System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction) at
System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction
transaction) at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection
owningObject) at
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection
owningConnection) at
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection
outerConnection, DbConnectionFactory connectionFactory) at
System.Data.SqlClient.SqlConnection.Open() at
System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user) at
System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe() at
System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode() at
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression
query) at
System.Data.Linq.ChangeDirector.StandardChangeDirector.DynamicInsert(TrackedObject
item) at System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject
item) at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) at
System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) at
System.Data.Linq.DataContext.SubmitChanges() at RegBook.classes.DbBase.Save() at
RegBook.usercontrols.BookingProcess.confirmBookingButton_Click(Object sender, EventArgs e)
解決
私はDTCにトランザクションをエスカレートしません提供されているコードを実現しました。 1つのトランザクション内で複数のデータコンテキストを使用しているとき、私は問題を得ていた。
私は思ったが、問題はまだoccuringた理由それはポートの範囲を必要と開いていたファイアウォールであった。
他のヒント
私の場合、私は、VPNを介してそれをしようとしていました。これは、VPNでLAN内ではなく、完全に罰金働いていました。私はまた、部位が、invainの両方でハードウェアファイアウォールのポート(すなわち、135,5000-5020)を開きました。その上に多くのことを検索した後、私は両方THEマシンはのNetBIOSネームTHEIRのとの通信が可能でなければならないことを知るようになりました。私は、hostsファイル内の別のMACHINのエントリを追加した&それは今完全に罰金wrokingされます。
おかげで貴重な助けのためのアンドリュー&マイクます。
ありがとうございます。
私は、あなたのアプリがインストールされているすべてのクライアントのためのポートとのconfigure MSDTCを開くことはできませんが、理解しています。 DTCへの促進からのTransactionScopeを阻止する方法はあります。 私は私が唯一のDBで働いています知っています。私は、エラーまたはエラーが発生した後に行われた変更を廃棄し、コンテキストにするために複数のコンテキストを必要としています。当然の最善の方法は、データコンテキストからオブジェクトを切り離すことであるが、この機能はSQLに.NET 3.5SP1のLINQでは使用できません。 私は別のコンテキストで変更を提出し、何かがうまくいかない場合はそれを捨てる必要はありそう。
ここで適切に動作するDTCを取得するために必要なすべての変更を加えることができ、いくつかのPowerShellスクリプトです。あなたは、トランザクションに参加している両方のマシン、つまりWebサーバーとSQL Serverマシン上でこれを実行する必要があります。
function Enable-MSDTC
{
[CmdletBinding()]
param()
Write-Host "Updating registry entries for MSDTC"
$msdtcRegKey = "HKLM:\SOFTWARE\Microsoft\MSDTC\Security"
Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessTransactions" -Value 1
Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccess" -Value 1
Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessOutbound" -Value 1
Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessClients" -Value 1
Set-ItemProperty -Path $msdtcRegKey -Name "NetworkDtcAccessInbound" -Value 1
Set-ItemProperty -Path $msdtcRegKey -Name "LuTransactions" -Value 1
#Configure MSDTC to use specific ports
#see: https://support.microsoft.com/en-us/kb/250367
$msdtcPortKey = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
New-Item -Path $msdtcPortKey
New-ItemProperty -Path $msdtcPortKey -Name "Ports" -PropertyType "MultiString" -Value "5000-5200"
New-ItemProperty -Path $msdtcPortKey -Name "PortsInternetAvailable" -PropertyType "String" -Value "Y"
New-ItemProperty -Path $msdtcPortKey -Name "UseInternetPorts" -PropertyType "String" -Value "Y"
#open firewall ports 135, 1433, 5000-5100
#also add MSDTC program exclusion
netsh advfirewall firewall add rule name='MSDTC Endpoint Mapper (In)' localport=135 dir=in action=allow protocol=TCP
netsh advfirewall firewall add rule name='MSDTC SQL Server (In)' localport=1433 dir=in action=allow protocol=TCP
netsh advfirewall firewall add rule name='MSDTC Dynamic Ports (In)' localport=5000-5200 dir=in action=allow protocol=TCP
netsh advfirewall firewall add rule name='MSDTC exe' dir=in action=allow program=$env:windir\system32\msdtc.exe enable=yes
Write-Host "Restarting MSDTC service"
#restart the MSDTC service
Restart-Service MSDTC -Force -Confirm:$false
}
Enable-MSDTC -ErrorAction SilentlyContinue