Introdução
Atualmente, grande parte dos desenvolvedores de software trabalha com aplicações que manipulam banco de dados relacionais, utilizando a linguagem SQL.
A linguagem SQL (Structured Query Language) ou Linguagem de Consulta Estruturada nasceu nos laboratórios da IBM na década de 70, e é a linguagem padrão para se trabalhar com bancos de dados relacionais.
A linguagem SQL pode ser dividida em vários subconjuntos, que são definidos de acordo com as operações que realizam. Podemos dividir a linguagem SQL em:
- DDL (Data Definition Language) – É o subconjunto responsável pela definição dos dados. O subconjunto DDL é utilizado para criar, alterar, e excluir tabelas em nossos bancos de dados, utilizando comandos como CREATE, ALTER, e DROP.
- DML (Data Manipulation Language) – É o subconjunto responsável pela manipulação dos dados. O DML é utilizado para selecionar, inserir, atualizar, e deletar dados, utilizando comandos como SELECT, INSERT, UPDATE, e DELETE.
- DCL (Data Control Language) – Subconjunto responsável pelo controle e autorização de acesso a dados, onde são utilizados comandos como: GRANT, REVOKE, e SET.
Os subconjuntos mais utilizados pelos desenvolvedores de software são DML e DDL, pois além de escrever rotinas para manipulação de dados (DML), muitos desenvolvedores também são responsáveis pela criação, alteração, e exclusão de tabelas em bancos de dados (DDL).
Durante a manipulação de um banco de dados, podem ocorrer falhas de hardware e/ou software, causando perda de dados. Para manipular os dados de forma segura e consistente, os sistemas gerenciadores de bancos de dados implementam o conceito de Transação.
Uma transação é um conjunto de alterações em um banco de dados que são executadas de maneira única. Para executar uma transação, os SGBDs obedecem a um conjunto de regras conhecidas com ACID, que visam proteger o banco de falhas e inconsistências.
Descrição das regras ACID:
- Atomicidade – As operações de uma transação só serão persistidas (COMMIT) se todas elas forem executadas com sucesso. Caso ocorram falhas, todas as operações da transação serão canceladas (ROLLBACK).
- Consistência – As transações devem respeitas as regras de integridade do banco, como chaves primárias, chaves estrangeiras, dentre outras, persistindo apenas dados válidos.
- Isolamento – Uma transação não pode sofrer interferências de transações concorrentes.
- Durabilidade – Quando uma transação é confirmada (COMMIT) os dados serão persistidos no banco, e podem ser recuperados.
A plataforma .NET conta com um framework extremamente poderoso para lidar com o acesso e a manipulação de dados, o ADO.NET.
Para estudar controle de transações utilizando estas tecnologias, iremos utilizar separação de camadas com DAO Pattern.
Para este artigo foi utilizado o Visual Studio Express 2012, e o SQL Server 2012 acessando uma instância LocalDB.
Criação do Projeto:
Listagem 1: Script para do Banco de Dados
CREATE TABLE Contatos(
codigo INT NOT NULL,
nome NVARCHAR(50) NOT NULL,
email NVARCHAR(50),
telefone NVARCHAR(10),
CONSTRAINT PK_USUARIOS PRIMARY KEY (codigo)
)
Utilizando o Visual Studio, crie uma nova Windows Forms Application.
Adicione no formulário da aplicação os seguintes controles:
- 05 controles do tipo Label
- 03 controles do tipo TextBox
- 01 controle do tipo MasktedTextBox (configurado para um campo Telefone)
- 02 controles do tipo Button
Organize os controles, e altere a propriedade Text dos controles conforme a figura abaixo:
Figura 1: Disposição dos controles no formulário
Altere o nome dos controles da seguinte forma:
- txbCodigo
- txbNome
- txbEmail
- mtbTelefone
- btnInserir
- btnGravar
Observação: Altere a propriedade TextMaskFormat do controle MaskedTextBox para "ExcludePromptAndLiterals", para não gravar a máscara no banco.
Adicione uma nova Class ao projeto, como o nome de ContatosMODEL, e implemente o código a seguir:
Listagem 2: Implementação dos métodos getters and setters da Classe ContatosMODEL
class ContatosMODEL
{
// Getters and Setters
public int codigo { get; set; }
public string nome { get; set; }
public string email { get; set; }
public string telefone { get; set; }
}
Adicione uma nova Class, com o nome de ContatosDAO, e implemente o método a seguir:
Na classe ContatosDAO, não esqueça de adicionar os seguintes Namespaces:
- using System.Data.SqlClient;
- using System.Windows.Forms;
- using System.Data;
Listagem 3: Método Gravar da Classe ContatosDAO
// método Gravar passando um objeto ContatosMODEL como parametro
public void Gravar(ContatosMODEL contato)
{
// cria um objeto para conexão. Perceba que estou utilizando uma instância LocalDB do SQL Server
SqlConnection conn = new SqlConnection(@"Server =(LocalDB)\v11.0;Database = banco; Integrated Security = SSPI;");
// cria objeto para controlar a transação
SqlTransaction transacao;
// abre a conexão;
conn.Open();
// inicia a transação
transacao = conn.BeginTransaction(IsolationLevel.ReadCommitted);
try
{
// objeto sql recebe uma instrução SQL, o objeto conn, e o objeto transacao
SqlCommand sql = new SqlCommand("Insert Into contatos (codigo, nome, " +
"email, telefone) Values (@codigo, " +
"@nome, @email, @telefone)", conn, transacao);
// parametros da instrução sql
sql.Parameters.AddWithValue("@codigo", contato.codigo);
sql.Parameters.AddWithValue("@nome", contato.nome);
sql.Parameters.AddWithValue("@email", contato.email);
sql.Parameters.AddWithValue("@telefone", contato.telefone);
sql.ExecuteNonQuery(); // executa a instrução no banco
transacao.Commit(); // commita a transação
conn.Close(); // fecha a conexao
}
catch (SqlException ex)
{
// Em caso de erros cancela (Rollback) a transação
transacao.Rollback();
MessageBox.Show(ex.Message); // mensagem contendo a SqlException
}
}
Voltando ao formulário, implemente o seguinte código no Evento Click do button btnInserir:
Listagem 4: Evento Click do button btnInserir
private void btnInserir_Click(object sender, EventArgs e)
{
txbCodigo.Clear();
txbNome.Clear();
txbEmail.Clear();
mtbTelefone.Text = "";
txbCodigo.Focus();
}
Implemente o seguinte código no Evento Click do button btnGravar:
Listagem 5: Evento Click do button btnGravar
private void btnGravar_Click(object sender, EventArgs e)
{
// verifica campos em branco
if (("".Equals(txbCodigo.Text)) | ("".Equals(txbNome.Text)))
{
MessageBox.Show("Verifique campos em branco","Contatos",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
ContatosMODEL contatosMODEL = new ContatosMODEL();
ContatosDAO contatosDAO = new ContatosDAO();
contatosMODEL.codigo = Convert.ToInt32(txbCodigo.Text);
contatosMODEL.nome = txbNome.Text;
contatosMODEL.email = txbEmail.Text;
contatosMODEL.telefone = mtbTelefone.Text;
contatosDAO.Gravar(contatosMODEL);
}
}
Conclusão
Nesse artigo aprendemos a implementar um controle de transações utilizando ADO.NET e C#.
Teste o código, refatore, e use a criatividade para implementar outros métodos, como consulta, atualização, delete, etc.
Um abraço.