martes, 4 de abril de 2017

Instrucciones COMMIT y ROLLBACK

COMMIT
Esta instruccion de SQL se utiliza para confirmar como permamentes las modificaciones realizadas en una transacción.
Begin tran
                   Insert into Mvtos Values (‘0150’, ‘Dep’, 1500, ’08-10-2008’)
                   Insert into Mvtos Values (‘7120’, ‘Ret’, 1500, ’08-10-2008’)
                   Update Cuentas Set Saldo = Saldo + 1 where Numero = ‘0150’
                   Update Cuentas Set Saldo = Saldo – 1 Where Numero = ‘7120’
Commit tran
Con la instruccion commit tran se pone una marca para saber hasta que punto se hizo la transaccion.

ROLLBACK
Esta funcion del SQL se utiliza para deshacer todas las modificaciones realizadas desde la última confirmación.

Ejemplo
Begin tran
                  <Comandos SQL>
                   <Comandos SQL>
         Save tran Puntoseg
                   <Comandos SQL>
                   <Comandos SQL>
         If @@ERROR <> 0
Rollback tran Puntoseg (cancela todo desde aquí hasta el punto de guardado)
         Else
                   Commit tran

Referencia: http://www.gayatlacomulco.com/tutorials/tallerdebasesdedatos/t44.htm

ROLLBACK (Comando)


Cancela los cambios realizados durante la transacción actual.

Observaciones

ROLLBACK restaura el estado en que se encontraban las tablas originales, los archivos memo de tablas y los archivos de índice antes de que comenzara la transacción.
Cuando se modifican registros de una base de datos que forma parte de una transacción, los demás usuarios de la red no tendrán acceso (lectura ni escritura) a los registros hasta que finalice la transacción.
Cuando otros usuarios de la red intenten tener acceso a los registros que usted ha modificado, deberán esperar hasta que usted finalice su transacción. Recibirán el mensaje "Registro no disponible... Espere" hasta que los registros estén disponibles. Por lo tanto, es importante que la duración de la transacción sea lo más breve posible o que realice la transacción a horas en las que otras personas no necesiten tener acceso a los registros.
ROLLBACK deshace los cambios efectuados durante la transacción actual. Si la transacción está anidada, sólo se desharán las modificaciones realizadas desde el anterior BEGIN TRANSACTION. La ejecución del programa continuará con la instrucción siguiente.
Si había algún bloqueo de registro o archivo, se liberará.

Ejemplo

En el siguiente ejemplo se abre la tabla customer de la base de datos testdata. Se establece el almacenamiento optimista en tablas para la tabla customer. Se muestra el contenido de los campos cust_id y company, y se reemplaza el contenido del campo company en los datos almacenados en búfer.
Se ejecuta BEGIN TRANSACTION para iniciar una transacción. Se ejecuta TABLEUPDATE para escribir los cambios en una tabla. Se muestra el nuevo contenido y se ejecuta ROLLBACK para restaurar el contenido original del campo company. Los campos cust_id y company se vuelven a mostrar con el campo company que contiene los valores originales.

CLOSE DATABASES
CLEAR

* Transactions are only supported within a DBC
OPEN DATABASE (HOME(2) + 'Data\testdata')

SET MULTILOCKS ON      && Required for buffering

USE customer
=CURSORSETPROP("Buffering",5)
? 'The original company field'
LIST FIELDS cust_id, company NEXT 5
REPLACE ALL company WITH "***" && Change field contents

BEGIN TRANSACTION
   =TABLEUPDATE(.T.)
   GO TOP
   ? 'The modified company field'
   LIST FIELDS cust_id, company NEXT 5
ROLLBACK           && Restore original field contents

=TABLEREVERT(.T.)
GO TOP
? 'The restored company field'
LIST FIELDS cust_id, company NEXT 5

Transacciones en MySQL

Introducción

El servidor de bases de datos MySQL soporta distintos tipos de tablas, tales como ISAM, MyISAM, InnoDB y BDB (Berkeley Database). De éstos, InnoDB es el tipo de tabla más importante (después del tipo predeterminado, MyISAM), y merece una atención especial.
Las tablas del tipo InnoDB están estructuradas de forma distinta que MyISAM, ya que se almacenan en un sólo archivo en lugar de tres, y sus principales características son que permite trabajar con transacciones, y definir reglas de integridad referencial.
El soporte de transacciones que provee MySQL no es algo nuevo en MySQL 4, ya que desde la versión 3.23 se podía hacer uso de tablas InnoDB, la única diferencia es que con la llegada de la versión 4.0 de MySQL, el soporte para este tipo de tablas es habilitado por default.
Las transacciones aportan una fiabilidad superior a las bases de datos. Si disponemos de una serie de consultas SQL que deben ejecutarse en conjunto, con el uso de transacciones podemos tener la certeza de que nunca nos quedaremos a medio camino de su ejecución. De hecho, podríamos decir que las transacciones aportan una característica de "deshacer" a las aplicaciones de bases de datos.
Para este fin, las tablas que soportan transacciones, como es el caso de InnoDB, son mucho más seguras y fáciles de recuperar si se produce algún fallo en el servidor, ya que las consultas se ejecutan o no en su totalidad. Por otra parte, las transacciones pueden hacer que las consultas tarden más tiempo en ejecutarse.
Seguramente alguna vez hemos escuchado hablar acerca de las transacciones, pero probablemente no entendemos bien lo que son, y como deben de ser usadas. La idea de este artículo es presentar algunos ejemplos para mostrar que no es nada complicado, y difícil de aprender.
En este artículo se asume que se cuenta ya con un servidor MySQL con soporte para el tipo de tablas InnoDB. En nuestro caso haremos uso de un servidor MySQL 4.013 ejecutándose en un sistema MSWindows.
Para asegurarnos que tenemos soporte para el tipo de tablas InnoDB podemos ejecutar la siguiente sentencia:
mysql> SHOW VARIABLES LIKE '%innodb%';
+---------------------------------+------------+
| Variable_name                   | Value      |
+---------------------------------+------------+
| have_innodb                     | YES        |
| innodb_additional_mem_pool_size | 1048576    |
| innodb_buffer_pool_size         | 8388608    |
| innodb_data_file_path           | ibdata:30M |
| innodb_data_home_dir            |            |
| innodb_file_io_threads          | 4          |
| innodb_force_recovery           | 0          |
| innodb_thread_concurrency       | 8          |
| innodb_flush_log_at_trx_commit  | 1          |
| innodb_fast_shutdown            | ON         |
| innodb_flush_method             |            |
| innodb_lock_wait_timeout        | 50         |
| innodb_log_arch_dir             | .         |
| innodb_log_archive              | OFF        |
| innodb_log_buffer_size          | 1048576    |
| innodb_log_file_size            | 5242880    |
| innodb_log_files_in_group       | 2          |
| innodb_log_group_home_dir       | .         |
| innodb_mirrored_log_groups      | 1          |
| innodb_max_dirty_pages_pct      | 90         |
+---------------------------------+------------+
20 rows in set (0.00 sec)
La variable más importante es por supuesto have_innodb que tiene el valor YES.
En efecto, una de las principales características de las tablas del tipo InnoDB es que pueden trabajar con transacciones, o sentencias SQL que son agrupadas como una sola. Un ejemplo típico de esto es una transacción bancaria. Por ejemplo, si una cantidad de dinero es transferida de la cuenta de una persona a otra, se requerirán por lo menos dos consultas:
UPDATE cuentas SET balance = balance - cantidad_transferida WHERE cliente = persona1;
UPDATE cuentas SET balance = balance + cantidad_transferida WHERE cliente = persona2;
Estas dos consultas deben trabajar bien, ¿pero que sucede si ocurre algún imprevisto y "se cae" el sistema después de que se ejecuta la primer consulta, pero la segunda aún no se ha completado?. La persona1 tendrá una cantidad de dinero removida de su cuenta, y creerá que ha realizado su pago, sin embargo, la persona2 estará enfadada puesto que pensará que no se le ha depositado el dinero que le deben. En este ejemplo tan sencillo se ilustra la necesidad de que las consultas sean ejecutadas de manera conjunta, o en su caso, que no se ejecute ninguna de ellas. Es aquí donde las transacciones toman un papel muy importante.
Los pasos para usar transacciones en MySQL son:
  • Iniciar una transacción con el uso de la sentencia BEGIN.
  • Actualizar, insertar o eliminar registros en la base de datos.
  • Si se quieren los cambios a la base de datos, completar la transacción con el uso de la sentencia COMMIT. Únicamente cuando se procesa un COMMIT los cambios hechos por las consultas serán permanentes.
  • Si sucede algún problema, podemos hacer uso de la sentencia ROLLBACK para cancelar los cambios que han sido realizados por las consultas que han sido ejecutadas hasta el momento.
Vamos a ejecutar algunas consultas para ver como trabajan las transacciones. Lo primero que tenemos que hacer es crear una tabla del tipo InnoDB e insertar algunos datos.
Para crear una tabla InnoDB, procedemos con el código SQL estándar CREATE TABLE, pero debemos especificar que se trata de una tabla del tipo InnoDB (TYPE= InnoDB). Esto es aplicable a cualquier tipo de tabla, pero cuando no se especifica nada, MySQL supone que se trata de una tabla MyISAM.
mysql> CREATE TABLE innotest (campo INT NOT NULL PRIMARY KEY) TYPE = InnoDB;
Query OK, 0 rows affected (0.10 sec)

mysql> INSERT INTO innotest VALUES(1);
Query OK, 1 row affected (0.08 sec)

mysql> INSERT INTO innotest VALUES(2);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO innotest VALUES(3);
Query OK, 1 row affected (0.04 sec)

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
+-------+
3 rows in set (0.00 sec)
De acuerdo, nada espectacular. Ahora veamos como usar transacciones.
mysql> BEGIN;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO innotest VALUES(4);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
+-------+
4 rows in set (0.00 sec)
Si en este momento ejecutamos un ROLLBACK, la transacción no será completada, y los cambios realizados sobre la tabla no tendrán efecto.
mysql> ROLLBACK;
Query OK, 0 rows affected (0.06 sec)

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
+-------+
3 rows in set (0.00 sec)
Ahora vamos a ver que sucede si perdemos la conexión al servidor antes de que la transacción sea completada.
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO innotest VALUES(4);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
+-------+
4 rows in set (0.00 sec)

mysql> EXIT;
Bye
Cuando obtengamos de nuevo la conexión, podemos verificar que el registro no se insertó, ya que la transacción no fue completada.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 449 to server version: 4.0.13

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.


mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
+-------+
3 rows in set (0.00 sec)
Ahora vamos a repetir la sentencia INSERT ejecutada anteriormente, pero haremos un COMMIT antes de perder la conexión al servidor al salir del monitor de MySQL.
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO innotest VALUES(4);
Query OK, 1 row affected (0.00 sec)

mysql> COMMIT;
Query OK, 0 rows affected (0.02 sec)

mysql> EXIT;
Bye
Una vez que hacemos un COMMIT, la transacción es completada, y todas las sentencias SQL que han sido ejecutadas previamente afectan de manera permanente a las tablas de la base de datos.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 450 to server version: 4.0.13

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
+-------+
4 rows in set (0.00 sec)

Lecturas consistentes

Por default, las tablas InnoDB ejecutan un lectura consistente (consistent read). Esto significa que cuando una sentencia SELECT es ejecutada, MySQL regresa los valores presentes en la base de datos hasta la transacción más reciente que ha sido completada. Si alguna transacción está en progreso, los cambios hechos por alguna sentencia INSERT o UPDATE no serán reflejados. Sin embargo, existe una excepción: las transacciones abiertas si pueden ver sus propios cambios. Para demostrar esto, necesitamos establecer dos conexiones al servidor MySQL.
Primero agregaremos un registro dentro de una transacción con la primera conexión (ID 524):
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 524 to server version: 4.0.13

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

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

mysql> INSERT INTO innotest VALUES(5);
Query OK, 1 row affected (0.00 sec)
Ahora, desde la segunda conexión (ID 525) consultamos los datos de nuestra tabla.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 525 to server version: 4.0.13

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
+-------+
4 rows in set (0.00 sec)
Como se puede observar, el registro que hemos insertado desde la 1ra. conexión no es regresado puesto que forma parte de una transacción que no ha sido completada. Ahora, desde la 1ra. conexión ejecutamos la misma consulta SELECT.
mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
|     5 |
+-------+
5 rows in set (0.00 sec)
Después de completar la transacción con una sentencia COMMIT en la 1ra. conexión podremos verificar que desde la 2da. conexión los cambios ya son visibles.
mysql> SELECT * FROM innotest;
+-------+
| campo |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
|     5 |
+-------+
5 rows in set (0.00 sec)

Otro ejemplo

En el ejemplo anterior hemos usado únicamente sentencias INSERT, sin embargo, sucede lo mismo con sentencias UPDATE o DELETE.
Vamos a crear una sencilla tabla llamada ventas que sea del tipo InnoDB.
mysql> CREATE TABLE ventas(
    -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> producto VARCHAR(30) NOT NULL,
    -> cantidad TINYINT NOT NULL) TYPE = InnoDB;
Query OK, 0 rows affected (0.96 sec)
Insertamos un registro.
mysql> INSERT INTO ventas VALUES(0,'Gansito marinela',3);
Query OK, 1 row affected (0.16 sec)

mysql> SELECT * FROM ventas;
+----+------------------+----------+
| id | producto         | cantidad |
+----+------------------+----------+
|  1 | Gansito marinela | 3        |
+----+------------------+----------+
1 row in set (0.01 sec)
Ahora vamos a iniciar una transacción con la sentencia BEGIN.
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
Actualizamos el registro.
mysql> UPDATE ventas SET cantidad=4 WHERE id=1;
Query OK, 1 row affected (0.07 sec)
Líneas correspondientes: 1  Cambiadas: 1  Avisos: 0
Verificamos que los cambios han sucedido.
mysql> SELECT * FROM ventas;
+----+------------------+----------+
| id | producto         | cantidad |
+----+------------------+----------+
|  1 | Gansito marinela | 4        |
+----+------------------+----------+
1 row in set (0.00 sec)
Si queremos deshacer los cambios, entonces ejecutamos un ROLLBACK.
mysql> ROLLBACK;
Query OK, 0 rows affected (0.06 sec)
Verificamos que se deshicieron los cambios.
mysql> SELECT * FROM ventas;
+----+------------------+----------+
| id | producto         | cantidad |
+----+------------------+----------+
|  1 | Gansito marinela | 3        |
+----+------------------+----------+
1 row in set (0.00 sec)
Vamos a actualizar el registro usando otra transacción.
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE ventas SET cantidad=2 WHERE id=1;
Query OK, 1 row affected (0.00 sec)
Líneas correspondientes: 1  Cambiadas: 1  Avisos: 0

mysql> SELECT * FROM ventas;
+----+------------------+----------+
| id | producto         | cantidad |
+----+------------------+----------+
|  1 | Gansito marinela | 2        |
+----+------------------+----------+
1 row in set (0.00 sec)
Vamos a confirmar que deseamos los cambios.
mysql> COMMIT;
Query OK, 0 rows affected (0.05 sec)
En este momento los cambios son permanentes y definitivos.
mysql> SELECT * FROM ventas;
+----+------------------+----------+
| id | producto         | cantidad |
+----+------------------+----------+
|  1 | Gansito marinela | 2        |
+----+------------------+----------+
1 row in set (0.00 sec)
Referencia: link

Convertidor de colores a BINARIO

LINK

Tabla de colores BRILLANTES en BINARIO


Tabla de colores en BINARIO



Programa #8

;=================================================================
 ; PROGRAMA : pt14_col
 ; FUNCION : imprime un texto con las letras de colores que parpadean
  ; REALIZADO POR : Yesenia Lizbeth Guerrero Garcia
  ; FECHA : Lunes 3 abril 2017
;=================================================================
 
 ; DECLARACION DE CONSTANTES

CR EQU 13            ; Constante CR (Retorno de carro) En decimal o
 LF EQU 10            ; Constante LF (Salto de l?nea) en hex es igual
 BIOS EQU 10H     ; Definicion de constantes o simbolos
 DOS EQU 21H
 TEXTO EQU 3
 FIN EQU 4C00H
 BIOS_10H EQU 10H

 ; DECLARACION DEL SEGMENTO DE DATOS

 DATOS SEGMENT ; Inicio del segmento de datos

     TITULO DB 'YESENIA_YARISETH_NANCY' ; Texto a imprimir
 COLORES DB 11001110B ; Atributo de 'Y' los numeros binarios se pueden convertir a hexa
 DB 11001111B ; Atributo de 'E' siendo dos digitos hexa el primero representa el
 DB 11000001B ; Atributo de 'S' fondo y el segundo el texto.
 DB 11001100B ; Atributo de 'E'
 DB 11000001B ; Atributo de 'N'
 DB 11001111B ; Atributo de 'I'
 DB 11001011B ; Atributo de 'A'
 DB 00101100B ; Atributo de '_'
 DB 00101111B ; Atributo de 'Y'
 DB 00101110B ; Atributo de 'A'
 DB 00100001B ; Atributo de 'R'
 DB 00101111B ; Atributo de 'I'
 DB 00100001B ; Atributo de 'S'
 DB 00101100B ; Atributo de 'E'
 DB 00100001B ; Atributo de 'T'
 DB 00101111B ; Atributo de 'H'
 DB 00101011B ; Atributo de '_'
 DB 11001100B ; Atributo de 'N'
 DB 11001111B ; Atributo de 'A'
 DB 11001110B ; Atributo de 'N'
 DB 11000001B ; Atributo de 'C'
 DB 11001111B ; Atributo de 'Y'


 DATOS ENDS ; Fin del segmento de datos

 ; DECLARACION DEL SEGMENTO DE PILA

PILA SEGMENT STACK       ; Inicio del segmento de pila

    DB 64 DUP('PILA')             ; Asignar espacio
   
    PILA ENDS                         ; Fin del segmento de pila

   
 ; DECLARACION DEL SEGMENTO DE CODIGO

 CODIGO SEGMENT           ; Inicio del segmento de código

 pt14_col PROC FAR             ; Inicio procedimiento pe14_col

 ASSUME CS:CODIGO,DS:DATOS,SS:PILA ; Indicar segmentos
 MOV AX,DATOS                                             ; Inicializar correctamente el
 MOV DS,AX                                                     ; registro de datos
 MOV AX,TEXTO                                             ; Establecer modo de texto 80x25 16 colores
 INT BIOS                                                          ; Interrupci?n BIOS pantalla (10H)
 MOV CX,22                                                      ; Bucle (22 caracteres)
 XOR SI,SI                                                          ; Contador de caracteres (SI=0)

BUCLE:
 PUSH CX                                                           ; Guardar CX (contador de bucle) en pila
 MOV DX,SI                                                        ; DX=SI (DX=contador)
 ADD DX,35                                                        ; Columna=35+contador
 MOV DH,12                                                       ; Establecer fila (12)
 CALL COLOCA                                                 ; Colocar el cursor
 MOV AL,[SI+OFFSET TITULO]                      ; Obtener caracter
 MOV BL,[SI+OFFSET COLORES]                   ; Obtener atributo
 CALL COLOR                                                    ; Imprimir caracter y atributo
 POP CX                                                                ; Recuperar CX (contador de bucle)
 INC SI                                                                  ; Incrementar contador o puntero
 LOOPNZ BUCLE                                                ; Repetir bucle mientras CX no sea 0
 MOV AH,8                                                           ; Esperar tecla
 INT DOS                                                              ; Interrupcion servicios del DOS (21H)
 XOR DX,DX                                                        ; Situar cursor en 0,0 (DH=0 y DL=0)
 CALL COLOCA                                                  ; Interrupcion servicios del DOS (21H)
 MOV AX,FIN                                                      ; Fin del programa
 INT DOS                                                              ; Interrupcion servicios del DOS (21H)
 pt14_col ENDP                                                    ; Fin del procedimiento pt14_col


  ;----------------------------------------------------------------------
 ; Definicion del procedimiento COLOR, que imprime un caracter en color
 ; Pasar en AL el codigo del caracter, y en BL el atributo
 ;----------------------------------------------------------------------
 COLOR PROC         ; Principio del procedimiento COLOR
 MOV AH,9               ; Servicio que escribe caracter y atrib
 XOR BH,BH             ; Numero de pagina de video (BH=0)
 INT BIOS                 ; Interrupcion BIOS pantalla (10H)

 RET ; Retornar
 COLOR ENDP           ; Fin del procedimiento COLOR
 ;----------------------------------------------------------------------
 ; Definición del procedimiento COLOCA, que situa el cursor en la pantalla
 ; Pasar en DH la fila y en DL la columna
 ;----------------------------------------------------------------------
 COLOCA PROC            ; Principio del procedimiento COLOCA
 MOV AH,2                     ; Servicio que coloca el cursor
 XOR BX,BX                   ; Numero de pagina de video (BH=0)
 INT BIOS                        ; Interrupcion BIOS pantalla (10H)
 RET                                  ; Retornar
 COLOCA ENDP              ; Final del procedimiento COLOCA


 CODIGO ENDS              ; Fin del segmento de codigo

 END pt14_col                 ; Fin del codigo e indicar direccion comienzo