Como usar transações COM + em um componente do Visual C++ .NET ou em um componente do Visual C++ 2005

Traduções deste artigo Traduções deste artigo
ID do artigo: 815814 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

RESUMO

Este artigo passo a passo descreve como usar COM + (Component Services) transações em uma classe de Microsoft Visual C++ .NET ou em uma classe de Microsoft Visual C++ 2005. Um conjunto de operações de banco de dados é considerado uma unidade. Ou todas as operações bem-sucedida ou, se uma operação falhar, toda a transação falhará. No último caso, quaisquer operações de banco de dados que foram tentadas serão lançadas para o banco de dados subjacente.

Requisitos

Este artigo pressupõe que você esteja familiarizado com os seguintes tópicos:
  • Conceitos transacionais e processamento
  • COM + (Component Services)

Serviços de transações COM +

Você pode implementar transação processamento com o namespace System.EnterpriseServices no Microsoft .NET Framework. Para acesso COM + serviços transacionais, crie uma classe. Para fazer isso, execute as seguintes etapas:
  1. Inicie o Visual Studio .NET ou Visual Studio 2005.
  2. No menu arquivo , aponte para novo e, em seguida, clique em Project .
  3. Em Project Types , clique em Projetos do Visual c++ e, em seguida, clique em Biblioteca de classe (NET) em modelos . Nome prjEnterprise projeto.

    Observação No Visual Studio 2005, clique em Visual C++ em Tipos de projeto e, em seguida, clique em Class Library em modelos .
  4. No Solution Explorer, clique com o botão direito do mouse em References e, em seguida, clique em Add Reference .
  5. Clique na guia NET na caixa de diálogo Add Reference .
  6. Clique duas vezes em System.EnterpriseServices em nome do componente .
  7. Certifique-se que System.EnterpriseServices aparece em Componentes selecionados e, em seguida, clique em OK .
  8. Adicione o código a seguir antes de quaisquer outras instruções no arquivo prjEnterprise.h:
    using namespace System;
    using namespace System::Data;
    using namespace System::Data::SqlTypes;
    using namespace System::Data::Common;
    using namespace System::EnterpriseServices;
    using namespace System::Data::SqlClient;
    
  9. Adicione uma nova classe é denominada clsES para o arquivo prjEnterprise.h.
  10. Para usar os serviços COM + transacional, certifique-se de que sua classe ( clsES ) herda a funcionalidade da classe ServicedComponent da seguinte maneira:
    public __gc class clsES:public ServicedComponent
    
  11. Use um atributo Transaction para especificar o nível de suporte transacional para a classe da seguinte maneira:
    [Transaction(TransactionOption::Required,Timeout=5)]public __gc class clsES:public ServicedComponent
    
  12. Crie um método na classe clsES que recebe quatro parâmetros de entrada inteiro. Nome dbAccess classe. Os primeiros dois parâmetros fornecem uma identificação do produto e as unidades em ordem para que o produto. Segundo dois parâmetros fornecem uma identificação do produto e as unidades em estoque para o produto. Esse método realiza um conjunto de operações de banco de dados em relação a estas identificações de produto especificado que precisam ser tratados como uma transação:
    public:	void dbAccess(int pID1, int onOrder, int pID2, int inStock)
  13. No método dbAccess , criar um objeto de conexão SQL para a Northwind banco de dados e abra a conexão. Operações de banco de dados ocorrerem usando o seguinte banco de dados:
    SqlConnection * Conn = new SqlConnection("user id=<username>;password=<password>;Initial Catalog=northwind;Data Source=<Your SQL Server name>;");
    Conn->Open();
    lembrar de Observação para alterar os parâmetros de seqüência de caracteres de conexão para refletir os valores corretos para seu servidor SQL.
  14. Defina um bloco try para capturar todas as exceções que podem ocorrer durante o processamento de banco de dados. Você deve capturar essas exceções para anular a transação. O bloco try inclui duas operações de banco de dados. Cada operação atualiza um campo diferente de um registro da tabela Produtos especificado.
    try { 
    
  15. Execute a primeira atualização para a tabela Produtos. Atualize o campo UnidadesPedidas com o valor onOrder do produto com identificação, como especificado nos dois primeiros parâmetros de entrada. Use o seguinte comando SQL para executar esta atualização SQL:
    SqlCommand * sqlCommand = new SqlCommand("UPDATE Products SET UnitsonOrder = @onOrderString WHERE productID = @pID1String ", Conn);
    sqlCommand->Parameters->Add(new SqlParameter("@onOrderString",SqlDbType::VarChar ,
    	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,onOrder.ToString()));
    sqlCommand->Parameters->Add(new SqlParameter("@pID1String", SqlDbType::VarChar,
    	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID1.ToString()));
    sqlCommand->ExecuteNonQuery();
    
  16. Execute outra atualização para a tabela Produtos. Atualizar o campo UnidadesEmEstoque com o inStock valor para o produto com identificação, como especificado nos parâmetros de entrada de terceiro e quarto. Use o seguinte comando SQL para executar esta atualização SQL:
    sqlCommand->Parameters->Add(new SqlParameter("@inStockString",SqlDbType::VarChar ,
    	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,inStock.ToString()));
    sqlCommand->Parameters->Add(new SqlParameter("@pID2String", SqlDbType::VarChar,
    	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID2.ToString()));
    sqlCommand->ExecuteNonQuery();
    
  17. Como essas atualizações são parte de uma transação COM +, eles são confirmados como uma unidade. O método setComplete da classe contextUtil do namespace System.EnterpriseServices é usado para confirmar a transação (nesse caso as duas atualizações) se nenhum erro foi gerado:
    ContextUtil::SetComplete(); 
    
  18. Use o seguinte código para fechar a conexão ao banco de dados Northwind:
    Conn->Close(); }
    
  19. Você deve capturar quaisquer exceções que ocorrem ao executar os comandos SQL para que você pode anular a transação inteira:
    catch(Exception * e){ 
    
  20. O método setAbort da classe contextUtil do namespace System.EnterpriseServices é usado para anular a transação inteira. Se a primeira atualização for bem-sucedida e a segunda actualização falha, nenhuma atualização é lançada a tabela Produtos. A detectada exceção é lançada para o chamador, indicando que a transação falhou:
    ContextUtil::SetAbort();
    throw e; }
    
  21. Para este componente funcionar corretamente, o componente deve ter um nome forte. Gerar um nome de alta segurança e, em seguida, assinar o assembly com nome forte. Para fazer isso, execute as seguintes etapas:
    1. No prompt de comando Visual Studio. NET, digite sn.exe -k snEnterprise.snk para criar um arquivo de chave. Para obter mais informações sobre assinatura de assemblies com nomes fortes, consulte a documentação do .NET Framework SDK.
    2. Copie snEnterprise.snk para a pasta de projeto.
    3. Em AssemblyInfo.vc, adicionar a linha de código a seguir antes ou depois outras instruções de atributo de assembly:
      [assembly:AssemblyKeyFileAttribute("..\\snEnterprise.snk")]; 
    4. Salve e, em seguida, criar seu projeto.

Listagem de código completo

Observação Remember to change your connection string parameters to reflect the correct values for your SQL Server server.
#pragma once

using namespace System;
using namespace System::Data;
using namespace System::Data::SqlTypes;
using namespace System::Data::Common;
using namespace System::EnterpriseServices;
using namespace System::Data::SqlClient;

namespace prjEnterprise
{
	
	[Transaction(TransactionOption::Required,Timeout=5)]
	public __gc class clsES:public ServicedComponent
	{
	public:	SqlConnection * Conn;

	public:	void dbAccess(int pID1, int onOrder, int pID2, int inStock)
		{
			try
			{			
				SqlConnection * Conn = new SqlConnection("user id=<username>;password=<password>;Initial Catalog=northwind;Data Source=<Your SQL Server name>;");
				Conn->Open();
				
				SqlCommand * sqlCommand = new SqlCommand("UPDATE Products SET UnitsonOrder = @onOrderString WHERE productID = @pID1String ", Conn);
				sqlCommand->Parameters->Add(new SqlParameter("@onOrderString",SqlDbType::VarChar ,
					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,onOrder.ToString()));
				sqlCommand->Parameters->Add(new SqlParameter("@pID1String", SqlDbType::VarChar,
					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID1.ToString()));
				sqlCommand->ExecuteNonQuery();
				
				sqlCommand->CommandText = "UPDATE Products SET UnitsinStock = @inStockString WHERE productID = @pID2String" ;
				sqlCommand->Parameters->Add(new SqlParameter("@inStockString",SqlDbType::VarChar ,
					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,inStock.ToString()));
				sqlCommand->Parameters->Add(new SqlParameter("@pID2String", SqlDbType::VarChar,
					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID2.ToString()));
				sqlCommand->ExecuteNonQuery();

				ContextUtil::SetComplete();
				Conn->Close();
			}
			catch(Exception * e)
			{
				ContextUtil::SetAbort();
			
				throw e;
			}			
		}
	};


}
Observação você deve adicionar o common language runtime oferecem suporte a compilador opção (/ CLR: oldSyntax) no Visual C++ 2005 a compilar com êxito o exemplo de código anterior. Para adicionar a opção de compilador de suporte de tempo de execução idioma comum no Visual C++ 2005, siga estas etapas:
  1. Clique em Project e clique em <ProjectName> propriedades .

    Observação <ProjectName> é um espaço reservado para o nome do projeto.
  2. Expanda Configuration Properties e, em seguida, clique em Geral .
  3. Clique para selecionar Common Language Runtime suporte, sintaxe antiga (/ CLR: oldSyntax) no projeto oferece suporte a Common Language Runtime configuração no painel à direita, clique em Aplicar e em seguida, clique em OK .
Para obter mais informações sobre o common language runtime oferece suporte à opção do compilador, visite o seguinte site da Microsoft:
/ clr (Common Language Runtime Compilation)
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

Verificar se ele funciona

Para testar esse código, crie um projeto Console Application que usa a classe clsES . Em um caso, uma transação for bem-sucedido, e os campos UnidadesEmEstoque e UnidadesPedidas para o produto especificado são atualizados. No segundo caso, a atualização para o campo UnidadesPedidas para um produto especificado tiver êxito, mas a atualização para o campo UnidadesEmEstoque para um produto falha porque o número de produto especificado não existe na tabela Produtos. Isso faz com que uma falha de transação e a transação é ignorada.
  1. Start Visual Studio .NET ou Visual Studio 2005.
  2. No menu arquivo , aponte para novo e, em seguida, clique em Project .
  3. Em Project Types , clique em Projetos do Visual c++ e, em seguida, clique em Aplicativo de console (NET) em modelos .

    Observação No Visual Studio 2005, clique em Visual C++ em Tipos de projeto e, em seguida, clique em Aplicativo de console CLR em modelos .
  4. Na caixa de texto nome , digite testES . Certifique-se que a opção Add to Solution é selecionada.
  5. Clique em OK para adicionar este projeto à solução.
  6. Para testES testar prjEnterprise , você deve adicionar uma referência. No Solution Explorer, clique com o botão direito do mouse referências em testES (que você acabou de adicionar) e, em seguida, clique em Add Reference .
  7. A caixa de diálogo Add Reference é exibida. Na guia projetos , clique duas vezes em prjEnterprise .
  8. Uma referência é exibida em selecionado componentes . Clique em OK para adicionar essa referência para o projeto.
  9. Adicione uma referência para o projeto para o namespace System.EnterpriseServices . No Solution Explorer, clique com o botão direito do mouse em References e, em seguida, clique em Add Reference .
  10. A caixa de diálogo Add Reference é exibida. Em Nome do componente na guia .NET , clique duas vezes em System.EnterpriseServices .
  11. Verifique se System.EnterpriseServices aparece em Componentes selecionados . Clique em OK .
  12. Clique com o botão direito do mouse testES e clique em Set as Startup Project .
  13. Cole o seguinte código fonte na função _tmain() da classe testES :
    prjEnterprise::clsES * myTest = new prjEnterprise::clsES();	
    try 
    {
    	myTest->dbAccess(1, 777, 2, 888);
    	Console::WriteLine("TRANSACTION ONE -- SUCCESS");
    
    		myTest->dbAccess(1, 5, 2, -20);
    	Console::WriteLine("TRANSACTION TWO -- SUCCESS");
    }
    catch (Exception * e)
    {
    	Console::WriteLine("TRANSACTION FAILURE");
    	//Console::WriteLine("Error Message: {0}",e->Message);	 
    	//uncomment this line if you must get detailed error information
    }
    
  14. Pressione F5 para executar o código de teste.

    No código da etapa 7, a primeira chamada para dbAccess terá êxito. Produto 1 e 2 do produto são na tabela Produtos. O campo onOrder para produto 1 é atualizado para 777 e o inStock campo para o produto 2 é atualizado para 888 . Porque esta transação bem-sucedida, você recebe a seguinte mensagem na janela de saída:
    TRANSAÇÃO ÊXITO DE UM-
    A segunda chamada para dbAccess falha. Portanto, nenhuma instrução de atualização em dbAccess à tabela Produtos é lançada para o banco de dados. Embora produto 1 pode ter seu campo UnidadesPedidas atualizado para 5 , produto 2 não pode ter seu campo UnidadesEmEstoque definido como -20 . Devido a uma restrição é definida na definição da tabela Produtos, UnidadesEmEstoque não é permitido com números negativos. Portanto, esta chamada para dbAccess falha, e toda a transação falha. A tabela Produtos permanece como estava antes da chamada para dbAccess . Notificação de falha na transação de dbAccess lida com a instrução catch e exibida a seguinte mensagem de erro na janela de saída:
    FALHA DE TRANSAÇÃO
  15. Examine o conteúdo da tabela Produtos Northwind usando o SQL Server Enterprise Manager. Quando você exibir produto 1, o campo UnidadesPedidas é igual a 777 . Quando você exibe produto 2, o campo UnidadesEmEstoque é 888 . Portanto, a segunda chamada para dbAccess (o que causaria valores diferentes para esses campos) falhará.

Solução de problemas

  • Certifique-se que qualquer projeto que usa serviços COM+ tenha um nome forte.
  • Qualquer classe que usa serviços COM + deve herdar a partir o componente de serviço. O componente de serviço está localizado no namespace System.EnterpriseServices .
  • Durante a depuração, uma transação pode ser tempo limite antes de ser confirmada ou anulada. Para evitar um tempo limite, use uma propriedade de tempo limite no atributo de transação. No exemplo a seguir, o método associado tem 1.200 segundos para concluir qualquer transação antes de ele expira:
    [Transaction(TransactionOption::Required,Timeout=1200)]
    
  • Você pode receber algumas exceções inesperadas ao executar o código. Para receber mais informações sobre essas exceções, Descomente as duas últimas linhas na etapa 13:
    Console::WriteLine("Error Message: {0}",e->Message);
    uncomment this line if you must get detailed error information

Referências

Para obter informações adicionais, visite o seguinte da Microsoft Developer Network (MSDN):
COM + Integration: Como .NET Enterprise Services podem ajudar a você criar aplicativos distribuídos
Componentes atendidos

Propriedades

ID do artigo: 815814 - Última revisão: quarta-feira, 14 de novembro de 2007 - Revisão: 3.2
A informação contida neste artigo aplica-se a:
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
Palavras-chave: 
kbmt kbsqlclient kbcomplusqc kbcode kbhowtomaster kbhowto KB815814 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 815814

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com