martes, 19 de julio de 2011

Fundamentos de Bases de Datos - Parte 2

Continuando la práctica vista anteriormente, retomaremos el principio del manejo de bases de datos, pero utilizando las características ACID que habías comentado anteriormente. No te preocupes, que aquí las explicaremos en gran medida para comprender el término de “Transacción” que es el que estaremos utilizando más adelante para nuestras operaciones.

Solamente recuerda que para ésta práctica retomaremos lo mismo que ya teníamos de la práctica pasada (aplicación, base de datos, enlace DSN, etc.). Y con esta medida, trataremos de explicar cómo funcionan en cierta medida los sistemas de los Bancos (o cualquier lugar donde ocupen sistemas de bases de datos) para responder ante los fallos o errores que pudieran surgir durante el tratamiento de su información.

PostgreSQL Global Development Group (1996-2011) define a las transacciones como elementos clave sobre todos los sistemas de bases de datos, pudiendo efectuar con estos elementos varios pasos dentro de uno mismo, u operaciones de todo o nada (es decir, o se efectúa todo un bloque de operaciones o no se efectúa ninguno). Los estados intermedios entre estos pasos no son visibles a otras transacciones, y en caso de la ocurrencia de algún error se prevé que la transacción se cancele sobre todos los pasos que la componen.

Si te fijas, la definición de transacciones que da PostgreSQL ® implica ciertas características importantes de los sistemas de bases de datos. Éstas características se conocen como ACID:
  • Atomicity (Atomicidad).- Se considera a cada transacción como una unidad de trabajo, o un bloque de operaciones, indicando con esto que o el trabajo se realiza en su totalidad (todo el bloque que comprende la transacción) o no se efectúa ninguna operación.
  • Coherency (Coherencia).- La transacción mantiene la coherencia de los datos, es decir, que si los datos están en un momento (estado) correcto antes de la transacción, también lo deben estar después de ella.
  • Isolating (Aislamiento).- Cada transacción se comporta como si fuera la única transacción dentro del sistema. Una transacción no tiene la posibilidad de ver las fases intermedias de otra transacción, hasta que terminan.
  • Durability (Durabilidad o Permanencia).- Si una transacción se realiza de forma satisfactoria, el sistema garantiza que los datos se mantienen aunque el equipo falle (Microsoft, 2011). 
Como puedes ver, el SMBD hace demasiadas cosas por nosotros, y precisamente, es el principio que trataremos de exponer aquí con nuestra aplicación en la base de datos, o se efectúa el bloque de operaciones que hayamos designado, o bien, no se efectúa ninguna, simulando que estamos comprando vía Internet, o directamente en el Banco, realizamos operaciones, y si hubo algún error en un momento determinado, regresaremos a un estado anterior de la transacción.

Para ello, retomaremos la información que nos proporciona PostgreSQL Global Development Group (1996-2011) en su sitio Web, para el manejo esencial de las transacciones en su SMBD. De entrada, algunos conceptos y comandos básicos:
  • BEGIN;.- Comando que indica el inicio de una transacción.
  • ROLLBACK;.- Retroceso a el estado anterior al inicio de la transacción.
  • COMMIT;.- Cumplimiento del bloque de transacción y aseguramiento de la persistencia de los datos que contiene dicha transacción.
  • SAVEPOINT nombrePunto;.- Generación de un punto intermedio de la transacción para regresar a dicho punto más que al inicio de la transacción.
Bueno, puede parecer confuso hasta este momento, pero hagamos un ejemplo sencillo, y luego se expondrá un video. Vamos siguiendo estos pasos:

BEGIN;
Select * from toperaciones;
Update toperaciones set ctienda=’ABCD’;
Select * from toperaciones;
ROLLBACK;
Select * from toperaciones;
COMMIT;

Parece extraño este código pero no lo es. Vamos explicándolo:
  1. Iniciamos el bloque de transacción con el comando “BEGIN;”
  2. Consultamos todos los registros de nuestra tabla “toperaciones” apareciendo en pantalla. 
  3. Actualizamos TODOS los registros cambiando el nombre de la tienda (¡oh!, un error severo). 
  4. Volvemos a consultar todos los registros y vemos que se ha hecho la actualización de los datos (técnicamente, el error). 
  5. Efectuamos un “ROLLBACK;” para regresar nuestra base de datos a su estado anterior. 
  6. Realizamos la consulta y vemos que todos nuestros datos persisten, es decir, se canceló la transacción regresando al punto inicial de la misma.
  7. Finalizamos la transacción con el comando “COMMIT;”.
Está interesante esta aplicación, pero podemos hacer más operaciones aún, utilizando los puntos de salvado (“savepoints”) para regresar a un punto determinado de la operación, y no solo al principio de la transacción:

BEGIN;
Select * from toperaciones;
Delete from toperaciones where ctienda=’Aurrera’;
Select * from toperaciones;
SAVEPOINT puntoguardado;
Delete from toperaciones;
Select * from toperaciones;
ROLLBACK TO puntoguardado;
Select * from toperaciones;
COMMIT;

La explicación de las operaciones:
  1. Iniciamos la transacción con el comando “BEGIN;”.
  2. Consultamos todos los registros de la tabla.
  3. Borramos todos los registros cuya tienda sea “Aurrera”, aclarando, esto no podremos recuperarlo posteriormente, pues está después del punto de guardado.
  4. Consultamos la tabla y vemos que se han borrado dichos registros.
  5. Generamos un punto de almacenamiento (al cual regresaremos) llamado “puntoguardado”.
  6. Borramos todos los registros.
  7. Consultamos que si se hayan borrado todos los registros (¡oh!, error nuevamente).
  8. Regresamos pero al punto guardado, no al inicio de la transacción, mediante el comando “ROLLBACK TO”.
  9. Consultamos y vemos que regresan todos los registros, excepto los que cuya tienda fuera “Aurrera”.
  10. Finalizamos la transacción con el comando “COMMIT;”.
Puede parecer un poco extraño este funcionamiento, pero en el siguiente video se da la explicación del uso de las transacciones utilizando la línea de comandos:

Video 1. Fundamento empírico de las transacciones en línea de comandos.


Con esto concluimos la explicación del primer punto, el uso de las transacciones dentro de nuestro SMBD. Ahora es momento de generar nuestra aplicación simulando las operaciones bancarias, donde tendrá las siguientes características de funcionamiento:
  • Se retomará el código pasado de las altas de datos (ventas) y consultas de datos.
  • Elegiremos cada qué número de operaciones se tendrá una consistencia de los datos (de 5 a 10 registros). 
  •  En caso de algún error se regresará al estado anterior siempre y cuando no se haya cumplido el número de operaciones de almacenamiento definidas (por ejemplo, si elegimos bloques de 5 operaciones, y efectuamos 6, solo podremos retroceder 1 operación, permaneciendo las 5 operaciones previas).
Mucho ruido y pocas nueces, vamos a ver cómo quedaría nuestro programa en vista de diseño:

·         Formulario: nombre “Form1”.
o   Botones:
“btnEjecutaConsulta”, texto “Ejecuta consulta”.
“btnCancelaConsulta”, texto “Cancela consulta”.
“btnAltaDatos”, texto “Ingresa venta”.
“btnEstableceRetroceso”, texto “Establece retroceso”.
“btnErrorOperacion”, texto “Error en operación”.
o   Cuadros de texto:
“txtCliente”, texto “1111222233334444”.
“txtCantidad”, texto “100.50”.
“txtTienda”, texto “Walmart”.
o   Etiquetas:
“lblNumeroCliente”, texto “Cliente: “.
“lblCantidad”, texto “Cantidad: “.
“lblTienda”, texto “Tienda: “.
o   Cuadros de opción:
“cmbEstableceRetroceso”, texto “5”, lista de datos: 5, 6, 7, 8, 9, 10.
o   Visor de datos (DataGridView): dgrDatos.

Tu formulario debe tener la siguiente forma:

Figura 1. Formulario bajo nuevo diseño:

Todo perfecto, es momento de explicar su código, que con respecto al tema pasado si ha cambiado un poco, pero trataremos de explicarlo lo más coherente posible, empecemos con las variables globales (les llamo variables aunque técnicamente según Visual Studio ® deberían ser objetos, pero bueno):

    Public conexion As OdbcConnection
    Public comando As OdbcCommand
    Public adaptador As OdbcDataAdapter
    Public conjunto As DataSet
    Public cantidadOperaciones As Integer
    Public contador As Integer
    Public puntosSalvados As Integer
    Public puntoUltimo As String

Las primeras cuatro variables las habíamos explicado anteriormente, por ello no se repetirán. Donde entra en juego ahora la transacción es en las siguientes variables:
  1. cantidadOperaciones.- Variable que irá almacenando cuántas operaciones se irán almacenando, y cada que lleguemos al valor predeterminado, se reiniciará.
  2. contador.- Variable común para recorrer las operaciones que llevamos.
  3. puntosSalvados.- Variable que almacena los bloques de transacciones, por ejemplo, si establecidos el almacenamiento cada 5 operaciones, y llevamos 10 registros, esta variable tendrá un valor de 2, si llevamos 12, valdrá igual 2, si llevamos 15, valdrá 3, etc.
  4. puntoUltimo.- Variable de tipo texto que almacena el último punto de retorno almacenado por nuestra aplicación.
El código correspondiente al inicio de la aplicación (la carga del formulario principal), que cambiará un poco respecto a lo que manejamos anteriormente:

        conexion = New OdbcConnection("dsn=odbcpostgres;uid=;pwd=;")
        comando = New OdbcCommand
        comando.Connection = conexion
        adaptador = New OdbcDataAdapter
        conjunto = New DataSet
        conexion.Open()
        MsgBox("Conexion establecida...", vbInformation)
        dgrDatos.Enabled = False
        btnEjecutaConsulta.Enabled = False
        cmdCancelaConsulta.Enabled = False
        cmdAltaDatos.Enabled = False
        lblNumeroCliente.Enabled = False
        txtCliente.Enabled = False
        lblCantidad.Enabled = False
        txtCantidad.Enabled = False
        lblTienda.Enabled = False
        txtTienda.Enabled = False
        btnErrorOperacion.Enabled = False
        puntosSalvados = 1

Nuevamente, existe código ya repetido del tema pasado (la conexión, la inicialización, etc.), lo único que cambia aquí es lo siguiente:
  1. Estamos “inhabilitando” diversos elementos de nuestro programa, específicamente aquellos que implican realizar operaciones, hasta que no se haga la elección del tamaño de transacciones de nuestro bloque.
  2. La variable “puntosSalvados” se inicializa con un valor de 1 (uno), puesto que estamos en el primer bloque de transacción.
El código que corresponde ahora es el del establecimiento de la cantidad de operaciones para nuestra transacción:

        dgrDatos.Enabled = True
        btnEjecutaConsulta.Enabled = True
        cmdCancelaConsulta.Enabled = True
        cmdAltaDatos.Enabled = True
        lblNumeroCliente.Enabled = True
        txtCliente.Enabled = True
        lblCantidad.Enabled = True
        txtCantidad.Enabled = True
        lblTienda.Enabled = True
        txtTienda.Enabled = True
        btnErrorOperacion.Enabled = True
        cantidadOperaciones = CInt(cmbEstableceRetroceso.Text)
        contador = 1
        btnEstableceRetroceso.Enabled = False
        cmbEstableceRetroceso.Enabled = False

Nada del otro mundo, salvo los siguientes detalles:
  1. Todo lo que teníamos “inhabilitado” se habilitará en este momento, pues como ya elegimos la cantidad de operaciones a considerar para nuestra transacción, podemos ya efectuar dichas operaciones.
  2. Inhabilitamos todo lo que tenga que ver con la elección de operaciones para la transacción, pues ya definimos previamente el tamaño.
  3. La variable “cantidadOperaciones” almacenará el bloque de operaciones que hayamos elegido del cuadro de opciones previamente.
  4. Se inicializa “contador” con un valor de 1 (uno) pues estamos en la primer operación.
Tras haber definido el bloque de transacciones es momento de ver los códigos que ya teníamos anteriormente, el de efectuar la consulta:

        comando.CommandText = "select * from toperaciones"
        adaptador.SelectCommand = comando
        conjunto.Clear()
        adaptador.Fill(conjunto)
        dgrDatos.DataSource = conjunto.Tables(0).DefaultView

Y el código de cancelar la consulta:

        dgrDatos.DataSource = Nothing

No se dan más detalles sobre los mismos puesto que ya habían sido explicados en el tema pasado y sería un tanto redundante comentarlos nuevamente. Vamos con el primer código interesante, el de ingresar una venta, recordando que ciertas fracciones de código ya fueron dadas en el tema pasado:

        Dim fechahora As Date
        Dim fecha As String
        Dim hora As String

        If (txtCantidad.Text = "" Or txtCliente.Text = "" Or txtTienda.Text = "") Then
            MsgBox("Error, dejaste algún parámetro sin contenido...", vbCritical)
        Else
            fecha = ""
            hora = ""

            fechahora = DateTime.Now
            fecha = fechahora.Year & "/"

            If fechahora.Month < 10 Then
                fecha = fecha & "0" & fechahora.Month & "/"
            Else
                fecha = fecha & fechahora.Month & "/"
            End If

            If fechahora.Day < 10 Then
                fecha = fecha & "0" & fechahora.Day
            Else
                fecha = fecha & fechahora.Day
            End If

            If fechahora.Hour < 10 Then
                hora = hora & "0" & fechahora.Hour & ":"
            Else
                hora = hora & fechahora.Hour & ":"
            End If

            If fechahora.Minute < 10 Then
                hora = hora & "0" & fechahora.Minute & ":"
            Else
                hora = hora & fechahora.Minute & ":"
            End If

            If fechahora.Second < 10 Then
                hora = hora & "0" & fechahora.Second
            Else
                hora = hora & fechahora.Second
            End If


            If contador = 1 Then
                comando.CommandText = "BEGIN;"
                comando.ExecuteNonQuery()
                comando.CommandText = "SAVEPOINT punto" & puntosSalvados & ";"
                puntoUltimo = "punto" & puntosSalvados
                comando.ExecuteNonQuery()
            End If

            comando.CommandText = "insert into toperaciones values ('" & fecha & "','" & hora & "','" & txtCliente.Text & "'," & txtCantidad.Text & ",'" & txtTienda.Text & "')"
            comando.ExecuteNonQuery()
            comando.CommandText = "select * from toperaciones"
            adaptador.SelectCommand = comando
            conjunto.Clear()
            adaptador.Fill(conjunto)
            dgrDatos.DataSource = conjunto.Tables(0).DefaultView
            MsgBox("Venta realizada exitosamente...", vbInformation)

            contador = contador + 1
            If (contador > cantidadOperaciones) Then
                puntosSalvados = puntosSalvados + 1
                contador = 1
                comando.CommandText = "COMMIT;"
                comando.ExecuteNonQuery()
            End If
        End If

Las fracciones de código que nos competen en estos momentos se explicarán a continuación:
  1. Si el contador vale uno (1) entonces es señal de que deberemos efectuar el inicio de la transacción, mediante la ejecución del comando “BEGIN;”.
  2. Generamos el punto de almacenamiento, mediante el comando “SAVEPOINT”, pasando como parámetro extra el punto en el cual nos encontramos (como se explicó anteriormente).
  3. Almacenamos la posición del punto en la variable “puntoUltimo”.
  4. Efectuamos el alta de los datos, tal y como hicimos en el tema pasado (“insert into toperaciones values….”).
  5. Las siguientes sentencias implican que tan pronto vamos insertando los datos en la tabla “toperaciones” se va actualizando el “DataGridView” (que este código es igual al de las consultas, por eso no se especifica más de él).
  6. Se incrementa la variable “contador”, para ver cuántas operaciones llevamos.
  7. Si el contador es mayor que el número válido de operaciones que tenemos (cantidadOperaciones), incrementamos el número de “puntosSalvados” en uno (1), reiniciamos el “contador”, y terminamos el bloque de transacción con uso del comando “COMMIT;”.
  8. Esto puede parecer extraño pero recuerda que determinamos que cada “N” operaciones se iba a generar el guardado de las mismas, y no podríamos regresar al punto anterior a ellas dentro de nuestro programa.
La última fracción de código que nos interesa es la de ejecución del botón en caso de ocurrir algún problema con nuestras operaciones (efectuar un “ROLLBACK;”):

        If contador <> 1 Then
            comando.CommandText = "ROLLBACK TO " & puntoUltimo & ";"
            comando.ExecuteNonQuery()
            MsgBox("Operación regresada al estado anterior...", vbInformation)
            comando.CommandText = "select * from toperaciones"
            adaptador.SelectCommand = comando
            conjunto.Clear()
            adaptador.Fill(conjunto)
            dgrDatos.DataSource = conjunto.Tables(0).DefaultView
            contador = 1
        End If

La explicación del código:
  1. Si el contador es distinto de uno (1), señal de que llevamos más de una operación.
  2. Efectuamos un “ROLLBACK;” al punto que nosotros hayamos definido mediante el uso de la variable “puntoUltimo”.
  3. Mostramos un mensaje indicando esta situación.
  4. Volvemos a consultar todos los datos para reflejar el cambio dentro del “DataGridView”.
  5. Si no llevamos ninguna operación de inicio del bloque de transacción, simplemente no podemos efectuar ninguno de estos comandos.
Listo, ya tenemos nuestra aplicación funcionando, pero, pues vamos a explicarla a detalle para ir demostrando su funcionamiento, de igual forma se ubicará un video explicando el funcionamiento de la aplicación. Empecemos con el inicio de la aplicación:

Figura 2. Interfaz inicial de la aplicación.

Vamos definir un bloque de transacción de 5 operaciones (es decir, cada 5 ventas se almacenará la información y no podremos regresar a un estado anterior):

Figura 3. Establecimiento del bloque de transacción.

Teniendo todo esto, ingresemos tres (3) ventas dentro de la tabla de operaciones:

Figura 4. Ventas ingresadas dentro de la tabla.

Generemos un error en la operación:

Figura 5. Mensaje informativo de retorno al punto anterior.

Vemos como dentro del “DataGridView” hemos regresado al punto anterior, señal de que hemos efectuado adecuadamente el “ROLLBACK;”. Vamos más allá, ingresemos siete (7) operaciones, cinco (5) operaciones con una tienda, y dos (2) operaciones con otra tienda:

Figura 6. Siete operaciones dentro de nuestra aplicación.

Hagamos la ejecución del error en la operación, y vemos cómo únicamente recuperamos las primeras cinco (5) operaciones, tal y como definimos dentro de nuestro bloque de transacciones:

Figura 7. Recuperación del bloque de transacción.

Si aún tras demostrar el funcionamiento de esta aplicación en este marco, tuvieras alguna duda, puedes observar el siguiente video, donde se demuestra, en tiempo real, el funcionamiento de esta aplicación que acabamos de generar:

Video 2. Sistema de transacciones en Visual Studio ®.

Con esto terminamos la utilización de las bases de datos, vinculadas con un lenguaje de programación, y mediante el uso de transacciones demostrando las propiedades ACID de los SMBD. Como se expresó, si algún motivo implica que el Banco, u otro servicio de cobranza, se ha hecho un cobro injusto, no le eches la culpa al SMBD, sino más bien a la aplicación que fue realizada (o a los hábiles vendedores que pasan dos veces tu tarjeta de crédito, ja, ja, ja).

Recuerda que se pueden armar cursos acorde a tus necesidades, tanto de sistemas computacionales, tecnologías educativas y educación en general, o bien, apoyo para tareas y desarrollo de proyectos conforme lo necesites. Actualmente ofrecemos los siguientes cursos ya disponibles y armados para su impartición conforme lo necesites:
 
  • Programación en Java con Swing.
  • Programación de sistemas Pocket PC.
  • Programación de Sistemas Palm.
  • Programación en lenguaje C (fundamentos de programación).
  • Programación en PHP.
  • Fundamentos de Bases de Datos.
De igual forma, la enseñanza es en línea, se resuelven dudas vía correo electrónico, chat, foros de discusión y distintos medios para que siempre estés comunicado y al pendiente de todo, y dispones del material completo vía Internet para su disposición cuando lo quieras, al momento que quieras y cuantas veces quieras. Para ello contamos con una plataforma de enseñanza en línea con varias herramientas para que estudies y aprendas de la mejor forma, a tu ritmo, conforme tus necesidades y enfatizando la comunicación en todo momento.

Pregunta por los cursos existentes o bien, si deseas, se te puede armar un curso acorde a tus necesidades de aprendizaje. Recordándote, tenemos (y podemos armar) cursos de los siguientes temas:

  • Sistemas Computacionales.
  • Control asistido por computadora.
  • Paquetes informáticos.
  • Lenguajes de programación.
  • Bases de datos.
  • Tecnologías educativas.
  • Educación en general.

Referencias.

Para descargar.

Si deseas descargar la información en formato de Microsoft ® Word para su posterior lectura, así como el código fuente de la aplicación, da click al enlace correspondiente:
  • Información en Microsoft ® Word: Enlace.
  • Código fuente de la aplicación: Enlace.

    No hay comentarios:

    Publicar un comentario