Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

tesla

Transações no mysql: compensa?

Recommended Posts

Pessoal, estou desenvolvendo um sistema de vendas, e quero o máximo de desempenho e portabilidade dele. Então vou utilizar a classe PDO para abstrair o SGDB, mas meu foco vai ser o MySQL pois ao contrário do que muitos me disseram, eu acredito que o MySQL tem suporte para um sistema bem grande de vendas. Porém, caso o cliente queira trabalhar com PostgreSQL eu tenho que oferecer suporte também.

 

Então preciso de um sistema de conexão segura com o MySQL, de forma que seja rápido. Logo pensei nas transações, mas fiquei na dúvida. Compensa usar transação no MySQL em um caso de um sistema de vendas, para aumentar o desempenho? O que acontece se o cliente fechar o browser antes de eu dar commit ou rollback?

 

Em questão de segurança, existe algum meio de conexão segura entre o PHP e o MySQL?

 

E a última pergunta: acham que o MySQL aguenta um sistema de vendas de grande porte? Na minha opinião sim, pois ele aguenta fóruns gigantes!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, do pouco que vi sobre transações estou falando de transações dentro do MySQL. No caso de por exemplo, eu realizar várias "alterações" em uma tabela, e só após o commit salvar no HD.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, nesse caso, eu não vejo porque utilizar transações dentro do MySQL até mesmo porque, você perde muito mais desempenho lá dentro.

Vendo de um modo geral, você não vai ter um savepoint pra cada ação alterada, ou não vai declarar flags pra cada retorno, porque isso iria

custar uma tonelada de processamento interno..

 

Eu vejo um motivo, em usar transações em sistema do tipo, no qual você tem uma alteração em massa dos dados, como por exemplo, entre 1 a 200 clientes, você altera todos de uma vez só, porem você esqueceu algum campo, e todos ficaram como NULL, então você precisa voltar ao estado anterior no MySQL, mais pelo que você descreveu sobre o seu problema ou dúvida, seria mais pro cara não ter 'completado uma informação' ou algo do tipo .. estou enganado ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Exato. Então no caso só de mudanças massivas? Por exemplo, eu tenho que atualizar um campo de 300 clientes, sendo que cada um deles vai depender de outro campo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

É só um exemplo hipotético. De um campo de uma tabela depender de outro. Mas e na questão do suporte do MySQL, acredita que ele consiga manter grandes bancos de dados?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Claro .. pode ficar na paz quanto a isso, agora .. não sei se expliquei bem sobre os savepoints, vai aí uma demonstração na qual eu te falei:

C:\Users\Andrey Knupp Vital>cd ..

C:\Users>cd ..

C:\>cd \dev\mysql\bin\

C:\dev\mysql\bin>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.41 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database usuarios;
Query OK, 1 row affected (0.00 sec)

mysql> use usuarios;
Database changed

mysql> create table usuarios(
   ->    uid int( 11 ) not null auto_increment,
   ->    nome varchar( 18 ) not null,
   ->   sobrenome varchar( 25 ) null,
   ->  primary key( `uid` )
   -> )Engine = InnoDB;
Query OK, 0 rows affected (0.07 sec)

mysql> begin work;
Query OK, 0 rows affected (0.03 sec)

mysql> insert into usuarios values( null, 'Andrey', 'Knupp Vital' );
Query OK, 1 row affected (0.00 sec)

mysql> select * from usuarios;
+-----+--------+-------------+
| uid | nome   | sobrenome   |
+-----+--------+-------------+
|   1 | Andrey | Knupp Vital |
+-----+--------+-------------+
1 row in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from usuarios;
Empty set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update usuarios set nome = 'Eduardo';
Query OK, 0 rows affected (0.03 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> savepoint crashBandicoot;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into usuarios values( null, 'André', 'Medeiros' );
Query OK, 1 row affected (0.01 sec)

mysql> rollback to savepoint crashBandicoot;
Query OK, 0 rows affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.05 sec)

mysql> select * from usuarios;
Empty set (0.01 sec)

mysql>

Crash Bandicoot (série) ;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Três coisa, uma para o tópico e duas por fora.

 

- Fora esse caso de atualizações em massa, qual outra aplicabilidade prática tem-se com transações?

 

Pode até ser que já está respondido, mas ainda não pesquei direito.

 

Imaginando um Cadastro de clientes de uma agência de recrutamento e seleção de pessoas (RH).

 

Se eu definir que todo cadastro de cada novo cliente deve obrigatoriamente passar por todas as etapas (cadastro de informações básicas, passando por formação acadêmica, experiência profissional e etc.).

 

Mesmo que algumas dessas "telas" ao longo do cadastro fiquem em branco, como pessoas que se encaixam nacategoria "Primeiro Emprego" (Experiência Profissional vazia) as transações seria uma maneira de, por exemplo, assegurar que esse cliente só seria cadastrado após completar todo o procedimento, isto é, na última tela?

 

Posso estar falando besteira mas, se de repente durante o processo de cadastro ocorre uma queda de força e o mesmo é interrompido no meio. As transações ajudariam em alguma coisa?

 

Ou cadastrar etapa pr etapa, a cada uma utilizando-se do ID do registro inicialmente gerado para criar futuros relacionamentos ainda é melhor?

 

Segundo: Como você copia a saída do prompt do DOS com aquilo que o MySQL gera em linha de comando?

 

Terceiro (esse é zueira): Por que quase sempre alguma "tragédia" ou "acidente de percurso"associa-se ao coitado do Crash? :lol:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bruno Augusto:

Botão Direito :seta: Selecionar Tudo, então aperta enter quando tudo for selecionado.

- Nem sempre eu uso o DOS pra colocar os resultados do MySQL aqui no fórum, as vezes uso o terminal do ubuntu.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pessoal, vocês sempre são uns mestres pra mim! ^_^

Agora é só procurar um contador ou alguém que esteja cursando contabilidade para montar a estrutura do banco de dados.

 

Resolvido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha, vou ter que discordar dos amigos com relação a transação.

 

Existe pelo menos 1 caso em que é fundamental usar transação (em um sistema de vendas, que é o seu caso) -> emissão de nota fiscal. Não por desempenho, e sim por integridade dos dados.

 

Normalmente em notas fiscais existe uma tabela com o cabeçalho da NF e outra tabela com os itens desta nota fiscal. Então, ao inserir uma NF seria usada uma transação, para evitar que existam, por exemplo cabeçalho de NF sem itens ou que faltem itens da NF.

 

Então, o fluxo do processo seria mais ou menos:

 

  • Inicia uma transação
  • Insere o cabecalho da nota fiscal
  • Insere os itens da NF
  • Caso dê tudo certo até aí, commit na transação
  • Se der alguma coisa errada, rollback na transação

 

Compreendeu a lógica?

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Matias, nesse caso sim .. mas também não podemos deixar de notar a situação que o cara se coloca em usar transactions, ainda mais internamente no modo que ele deseja fazer. O único modo que ele tem pra verificar os dados internamente, seria com Procedures ou Views .. no qual pudesse declarar variáveis com erros disparados. Pra daí sim fazer um rollback nos dados. fora isso, você não tem como saber internamente no MySQL se teve uma ocorrência seja de erro ou de falta de dados em uma tabela. então, seria algo do tipo:

C:\dev\mysql\bin>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.41 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use teste;
Database changed

mysql> delimiter $$
mysql> create procedure exemplo()
   ->    language sql
   ->    not deterministic
   ->    contains sql
   ->    sql security definer
   ->  begin
   ->       declare lasterror smallint(6);
   ->       set lasterror = @@warning_count;
   ->       if lasterror >= 1 then
   ->          select 'Erro .. fazendo rollback';
   ->          rollback;
   ->       else select 'Nenhum erro .. fazendo commit';
   ->       end if;
   ->  end$$
Query OK, 0 rows affected (0.03 sec)

mysql> call exemplo()$$
+-------------------------------+
| Nenhum erro .. fazendo commit |
+-------------------------------+
| Nenhum erro .. fazendo commit |
+-------------------------------+
1 row in set (0.02 sec)

Query OK, 0 rows affected (0.03 sec)

mysql>

 

Olha, andei pensando sobre o que o Matias Rezende falou, até me deu uma idéia:

C:\dev\mysql\bin>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.41 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use teste;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_teste |
+-----------------+
| teste           |
+-----------------+
1 row in set (0.03 sec)

mysql> delete from teste;
Query OK, 5 rows affected (0.02 sec)

mysql> create table teste1(
   ->        codigo int( 11 ) not null,
   ->        data timestamp
   -> )engine = innodb;
Query OK, 0 rows affected (0.12 sec)

mysql> insert into teste values( 1, null );
Query OK, 1 row affected (0.00 sec)

mysql> insert into teste values( 2, null );
Query OK, 1 row affected (0.00 sec)

mysql> insert into teste values( 3, null );
Query OK, 1 row affected (0.00 sec)

mysql> insert into teste values( 4, null );
Query OK, 1 row affected (0.00 sec)

mysql> insert into teste values( 5, null );
Query OK, 1 row affected (0.00 sec)

mysql> select * from teste;
+--------+---------------------+
| codigo | data                |
+--------+---------------------+
|      1 | 2011-07-12 11:56:33 |
|      2 | 2011-07-12 11:56:37 |
|      3 | 2011-07-12 11:56:39 |
|      4 | 2011-07-12 11:56:42 |
|      5 | 2011-07-12 11:56:44 |
+--------+---------------------+
5 rows in set (0.00 sec)

mysql> delimiter $$

mysql> create procedure exemplo()
   ->  language sql
   ->  not deterministic
   ->  contains sql
   ->  sql security definer
   ->  begin
   ->       declare exit handler for sqlexception rollback;
   ->       declare exit handler for not found rollback;
   ->       declare exit handler for sqlwarning rollback;
   ->       start transaction;
   ->           call exemplo1();
   ->       commit;
   -> end$$
Query OK, 0 rows affected (0.00 sec)

mysql> create procedure exemplo1()
   ->  language sql
   ->  not deterministic
   ->  contains sql
   ->  sql security definer
   ->  begin
   ->  declare dt datetime;
   ->  declare cur cursor for select `data` from `teste`;
   ->  open cur;
   ->     begin
   ->        declare exit handler for sqlstate '02000' begin end;
   ->        loop
   ->            fetch cur into dt;
   ->            insert into teste1( `data` ) values( dt );
   ->        end loop;
   ->      end;
   ->  close cur;
   -> end$$
Query OK, 0 rows affected (0.01 sec)

mysql> select * from teste1$$
Empty set (0.00 sec)

mysql> select * from teste$$
+--------+---------------------+
| codigo | data                |
+--------+---------------------+
|      1 | 2011-07-12 11:56:33 |
|      2 | 2011-07-12 11:56:37 |
|      3 | 2011-07-12 11:56:39 |
|      4 | 2011-07-12 11:56:42 |
|      5 | 2011-07-12 11:56:44 |
+--------+---------------------+
5 rows in set (0.00 sec)

mysql> call exemplo()$$
Query OK, 0 rows affected, 0 warnings (0.08 sec)

mysql> select * from teste1$$
+--------+---------------------+
| codigo | data                |
+--------+---------------------+
|      0 | 2011-07-12 11:56:33 |
|      0 | 2011-07-12 11:56:37 |
|      0 | 2011-07-12 11:56:39 |
|      0 | 2011-07-12 11:56:42 |
|      0 | 2011-07-12 11:56:44 |
+--------+---------------------+
5 rows in set (0.00 sec)

mysql>

 

Na hora que eu postei o primeiro código, tava corrido .. horário de almoço .. etc, então veja o exemplo acima podemos declarar handlers no qual vai executar o rollback em uma das situações. o exemplo acima, faz o seguinte pega todos os dados da tabela 'teste' pra jogar na tabela 'teste1', desculpem a criatividade com os campos mas isso foi demonstrativo, enfim .. mas você pode ver ou até testar, que se eu criar o procedure e não declarar um exit handler pra um cursor que possivelmente não tenha um registro encontrado na tabela ele não vai inserir os dados na outra tabela. isso torna a sua tabela com uma integridade melhor, e se não me engano o SQLState 02000 é 'zero rows found' .. algo assim, não procurei, então .. considere isso como exemplar

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.