JAK: Provádět distribuované transakce pomocí zprostředkovatele .NET pomocí ServicedComponent v jazyce Visual C# .NET

Microsoft Visual Basic .NET verzi tohoto článku naleznete v 316627 .


Tento článek se týká následujících oborů názvů knihovny tříd rozhraní.NET Framework společnosti Microsoft:

  • System.Data.SqlClient
  • System.EnterpriseServices
  • System.Runtime.CompilerServices
  • System.Reflection

V TOMTO ÚKOLU

Souhrn

Tento článek ukazuje, jak provádět distribuované transakce pomocí zprostředkovatele .NET ServicedComponent třídy. Ačkoli v tomto článku používá zprostředkovatele SqlClient .NET proti serveru Microsoft SQL Server, můžete použít také ODBC nebo OLE DB .NET spravovaného zprostředkovatele.

Požadavky

Následující seznam obsahuje doporučený hardware, software, síťovou infrastrukturu a požadované aktualizace service Pack:

  • Microsoft Windows 2000 Professional, Microsoft Windows 2000 Server, Microsoft Windows 2000 Advanced Server
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server 7.0 nebo Microsoft SQL Server 2000

Přehled

Instance třídy rozhraní.NET Framework mohou účastnit automatické transakce Pokud připravit třídy k tomu. Každý zdroj, který přistupuje k instanci třídy nebo objektu se využívá v transakci. Například pokud objekt používá ADO.NET účtovat peníze na účtu v databázi, správce prostředků pro databázi Určuje, zda objekt spuštěn v transakci. Pokud objekt měli spustit v transakci, správce prostředků využívá automaticky databáze v transakci.

K přípravě třídy účastnit automatické transakce, použijte následující postup:

  1. Použíjte třídu TransactionAttribute do třídy určit typ automatické transakce, která komponenta vyžaduje.

    Typ transakce musí být členem výčtu TransactionOption .
  2. Odvození třídy od třídy ServicedComponent . ServicedComponent je základní třída všech tříd, které používají služby COM +.
  3. Podepište sestavení silným názvem a ujistěte se, že sestavení obsahuje jedinečnou dvojici klíčů.
  4. Zaregistrujte sestavení, které obsahuje vaši třídu s katalogu modelu COM +.

    Poznámka: Pokud společný jazykový modul runtime spravuje klienta, který volá instanci své třídy, můžete je provedena registrace. Tento krok je nutný pouze v případě, že vytvoří nespravovaná volající a volá instance třídy. Použijte nástroj pro instalaci služeb .NET (Regsvcs.exe) ručně zaregistrovat sestavení.
Další informace o tom, jak podepsat sestavení se silným názvem naleznete v následujícím tématu v Microsoft rozhraní.NET Framework Developer's Guide:

Podepisování sestavení silným názvem
http://msdn.microsoft.com/en-us/library/xc31ft41.aspx
Další informace o tomto procesu naleznete v následujícím tématu v Microsoft rozhraní.NET Framework Developer's Guide:

Automatické transakce a tříd rozhraní.NET Framework
http://msdn.microsoft.com/en-us/library/ms123400.aspx

Vytvoření projektu

  1. Takto vytvořit nový projekt aplikace konzoly v aplikaci Visual C# .NET:
    1. Spusťte aplikaci Visual Studio .NET.
    2. V nabídce soubor přejděte na příkaz Nový a klepněte na příkaz projekt.
    3. V dialogovém okně Nový projekt klepněte na tlačítko Projekty Visual C# v části Typy projektua klepněte na tlačítko Aplikace konzoly v části šablony.
    4. V Průzkumníku řešení přejmenujte soubor Class1.cs jako DistributedTransaction.cs.
  2. Odstraňte všechny kód ze souboru DistributedTransaction.cs.
  3. V nabídce projekt klepněte na tlačítko Přidat odkaza poté přidejte následující odkazy:
    • System.EnterpriseServices
    • System.Data.dll

  4. V souboru AssemblyInfo.cs zakomentujte následující řádky kódu:
    [assembly: AssemblyKeyFile("")][assembly: AssemblyKeyName("")]

  5. Přidejte následující kód do souboru DistributedTransaction.cs:
    using System;using System.Data.SqlClient;
    using System.EnterpriseServices;
    using System.Runtime.CompilerServices;
    using System.Reflection;

    [assembly: ApplicationName("DistributedTransaction")]
    [assembly: AssemblyKeyFileAttribute("..\..\DistributedTransaction.snk")]


    namespace DistributedTransaction
    {
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
    try
    {
    DistributedTran myDistributedTran = new DistributedTran();
    myDistributedTran.TestDistributedTransaction();
    }
    catch (System.Data.SqlClient.SqlException e)
    {
    System.Console.WriteLine("Transaction Aborted: Error returned: " + e.Message);
    }
    }
    }
    /// <summary>
    /// Summary description for TestApp.
    /// </summary>
    [Transaction(TransactionOption.Required)]
    public class DistributedTran: ServicedComponent
    {
    public DistributedTran()
    {
    }
    [AutoComplete]
    public string TestDistributedTransaction()
    {
    // The following Insert statement goes to the first server.
    // This Insert statement does not produce any errors.
    String insertCmdSql = "Insert Into TestTransaction (Col1, Col2) Values (1,'Sql Test')";

    // The following Delete statement goes to the second server.
    // Because the table does not exist, this code throws an exception.
    String exceptionCausingCmdSQL = "Delete from NonExistentTable";

    // The following connection strings create instances of two SqlConnection objects
    // to connect to two different SQL Server servers in your environment.
    // Modify the connection strings as necessary for your environment.
    SqlConnection SqlConn1 = new SqlConnection("Server=Server_Name;uid=User_Id;database=DatabaseName;pwd=Password");
    SqlConnection SqlConn2 = new SqlConnection("Server=Server_Name;uid=User_Id;database=DatabaseName;pwd=Password");

    try
    {
    SqlCommand insertCmd = new SqlCommand(insertCmdSql,SqlConn1);
    SqlCommand exceptionCausingCmd = new SqlCommand(exceptionCausingCmdSQL,SqlConn2);

    // This command runs properly.
    insertCmd.Connection.Open();
    insertCmd.ExecuteNonQuery();


    // This command results in an exception, which automatically rolls back
    // the first command (the insertCmd command).
    exceptionCausingCmd.Connection.Open();
    int cmdResult = exceptionCausingCmd.ExecuteNonQuery();

    SqlConn1.Close();
    SqlConn2.Close();

    Console.WriteLine("Hello");

    }
    catch (System.Data.SqlClient.SqlException ex)
    {
    // After you catch the exception in this function, throw it.
    // The service component receives this exception and
    // aborts the transaction. The service component then
    // throws the same exception, and the calling function
    // receives the error message.
    Console.WriteLine (ex.Message);
    throw (ex);
    }
    finally
    {
    // Close the connection.
    if (SqlConn1.State.ToString() == "Open")
    SqlConn1.Close();

    if (SqlConn2.State.ToString() == "Open")
    SqlConn2.Close();
    }

    return "Success";

    }

    }
    }

  6. V nabídce soubor klepněte na příkaz Uložit vše.
  7. Klepněte na tlačítko Start, přejděte na příkaz programy, Microsoft Visual Studio.NET, Visual Studio .NET nástrojea potom klepněte na tlačítko Příkazový řádek sady Visual Studio .NET.
  8. Otevřete složku obsahující projekt a potom spusťte následující příkaz, chcete-li podepsat sestavení silným názvem:
    sn -k DistributedTransaction.snk
  9. Sestavte aplikaci.
  10. Na prvním serveru SQL Server, vytvořte v následující tabulce:
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestTransaction]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[TestTransaction]
    GO

    CREATE TABLE [dbo].[TestTransaction] (
    [Col1] [int] NULL ,
    [Col2] [varchar] (100) NULL
    ) ON [PRIMARY]
    GO

  11. Spusťte aplikaci. Všimněte si, že obdržíte následující chybovou zprávu (což je očekávané chování):
    Přerušené transakce: Vrácena chyba: Neplatný objekt název 'NonExistentTable'.
  12. Otevřete SQL Server Query Analyzer, přidejte následující kód a stiskněte klávesu F5 pro spuštění dotazu:
    USE NORTHWIND;SELECT * FROM TestTransaction WHERE Col1=1 AND Col2='Sql Test'

    Všimněte si, že dotaz nevrací všechny řádky, protože transakce byla přerušena.
  13. Vyhledejte následující kód v projektu Visual C#:
    String exceptionCausingCmdSQL = "Delete from NonExistentTable";
    a nahraďte příkaz SQL platný dotaz nezpůsobí přerušit transakci. Například:
    String exceptionCausingCmdSQL = "Select @@Identity from customers";
  14. Stisknutím klávesy F5 kompilace a spuštění aplikace znovu.
  15. V kroku 12 v Query Analyzer spusťte příkaz znovu. Všimněte si, že dotaz vrátí řádek, protože transakce byla schopna úspěšně dokončena.
Poznámky:

  • V tomto příkladu neprovádí zpracování chyb.
  • Pro všechny klienty a servery musí být spuštěn SQL Server a Microsoft Distributed Transaction Coordinator (MS DTC).

Odkazy

Další informace získáte klepnutím na níže uvedené číslo článku znalostní báze Microsoft Knowledge Base:

306296 jak: Vytvoření komponenty obsluhované .NET používající transakce v aplikaci Visual C# .NET
Vlastnosti

ID článku: 316247 - Poslední kontrola: 20. 1. 2017 - Revize: 1

Váš názor