Código Fuente: Transacciones Bancarias con Java

Codigos

Los bancos, las instituciones financieras, las compañías de tarjetas de crédito y otras empresas que mantienen registros de transacciones financieras utilizan sistemas concurrentes, que están diseñados para soportar y ejecutar muchas transacciones juntas.

Concepto de sistema de transacciones bancarias
Concepto de sistema de transacciones bancarias

¿Te imaginas que una empresa financiera realice un préstamo online varias veces al mismo tiempo y lo registre como única vez? Eso sería fatal. Plataformas como Moneezy, que compara préstamos, enumera una lista de financieras que utilizan software muy seguro para las transacciones.

Estas transacciones bancarias se componen de diferentes secuencias de acciones, y no deben dar cabida al error. Entonces, ¿cómo puedes implementar un sistema en Java basado en transacciones y de forma segura? Te presentaré 3 ejemplos con diferentes enfoques:

  • Enfoque principiante
  • Enfoque multihilo
  • Uso de la sincronización en el enfoque multihilo (más seguro)

Para entenderlo, veamos primero una ilustración para implementar el enfoque.

Antes de continuar, uno debe tener una fuerte comprensión sobre Java POO, Java Multihilo y Java Interrupted-Exception (excepción interrumpida). Si no es así, repáselos ya que el título en sí mismo es una pura implementación de multihilo.

Ilustración de Ejemplo

Vamos a discutir la arquitectura del sistema de transacciones bancarias utilizando java. A lo largo de este ejemplo, te llevaré de la mano por todo el procedimiento de la transacción y lo haré fácil de entender para que puedas incluso explicarlo a tus amigos. Para simplificar, hemos considerado una cuenta bancaria conjunta con 5 propietarios (Alex, Mónica, Martha, Ronald y Santiago) y el saldo inicial es de cien dólares ($100). Las transacciones de la cuenta son las siguientes:

NombreSaldo($)Retiro($)Depósito($)ComentarioSaldo Final($)
Alex10020 Alex retiró 20
Saldo después del retiro: 80     
80
Mónica8040 Mónica retiró 40
Saldo después del retiro: 40
40
Martha40 35Martha depositó 35
Saldo después del depósito: 75
75
Ronald7580 Ronald no puedes retirar 80
Tu saldo es: 75
75
Santiago7540 Santiago retiró 40after withdrawal: Saldo después del retiro: 3535

Enfoque 1: Enfoque Principiante

Hemos declarado los métodos “withdraw” y “deposit” dentro de la clase “Banca” y accedemos a ellos desde la clase del controlador “GFG” creando un objeto “obj” de la clase Banca.

Código Fuente:

// Programa Java para ilustrar el sistema de transacciones bancarias
// Clase Banca
// Definición de la operación bancaria
class Banca {
    // Saldo inicial de 100$
    int total = 100;
    // Método de retirada de dinero. Retirar sólo si
    // el dinero total es mayor o igual al dinero
    // solicitado para la retirada
    // Método
    // Para retirar dinero
    void withdrawn(String name, int withdrawal)
    {
        if (total >= withdrawal) {
            System.out.println(name + " retiró "
                    + withdrawal);
            total = total - withdrawal;
            System.out.println("Saldo después del retiro: "
                    + total);
            // Hacer que el hilo duerma durante 1 segundo después de
            // cada retiro
            // Bloque Try para comprobar las excepciones
            try {
                // Hacer que el hilo se duerma durante 1 segundo
                Thread.sleep(1000);
            }
            // Bloque catch para manejar las excepciones
            catch (InterruptedException e) {
                // Mostrar la excepción junto con el
                // número de línea
                // utilizando el método printStacktrace()
                e.printStackTrace();
            }
        }
        // Si el dinero solicitado para la retirada es mayor
        // que el saldo, entonces deniega la transacción*/
        else {
            // Imprimir declaraciones
            System.out.println(name
                    + " no puedes retirar "
                    + withdrawal);
            System.out.println("Tu saldo es: " + total);
            // Hacer que el hilo duerma durante 1 segundo después de
            // cada fallo de transacción
            // Bloque Try para comprobar las excepciones
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    // Método - para depositar dinero
    // Aceptar dinero siempre que se deposite
    void deposit(String name, int deposit)
    {
        System.out.println(name + " depositó " + deposit);
        total = total + deposit;
        System.out.println("Saldo después del depósito: "
                + total);
        // Hacer que el hilo duerma durante 1 segundo después de
        // cada depósito
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// Clase principal
class GFG {
    // Método principal
    public static void main(String[] args)
    {
        // Declarar un objeto de la clase Banca y llamar
        // a los métodos withdarwn y deposit
        // con los parámetros adecuados
        // Creación de un objeto de la clase Banca dentro de main()
        Banca obj = new Banca();
        // Entrada personalizada - Transacciones
        obj.withdrawn("Alex", 20);
        obj.withdrawn("Mónica", 40);
        obj.deposit("Martha", 35);
        obj.withdrawn("Ronald", 80);
        obj.withdrawn("Santiago", 40);
    }
}

Salida:

Alex retiró 20
Saldo después del retiro: 80
Mónica retiró 40
Saldo después del retiro: 40
Martha depositó 35
Saldo después del depósito: 75
Ronald no puedes retirar 80
Tu saldo es: 75
Santiago retiró 40
Saldo después del retiro: 35
Ejemplo 1 de operación bancaria en Java
Ejemplo 1 de operación bancaria en Java

Hay ciertos contras asociados con el enfoque básico como se describe a continuación:

No hay dos personas que puedan hacer transacciones al mismo tiempo, una tiene que esperar hasta que la primera termine su transacción. Si el número de personas es grande, hay que esperar y esperar hasta que llegue nuestro turno. Para demostrar este problema, podemos hacer que el hilo duerma durante 3 segundos durante cada transacción. En la vida real, esto tomaría mucho tiempo haciendo que este enfoque sea incapaz de ser implementado en proyectos de transacciones reales.

Método 2: Enfoque multihilo

¿Cómo puede ayudar el multihilo?

El multihilo permite que diferentes hilos trabajen al mismo tiempo sin depender unos de otros. Así, un gran grupo de hilos puede realizar una operación al mismo tiempo.

Código Fuente:

// Programa Java para ilustrar el sistema de transacciones bancarias
// Clase Banca
// Definición de la operación bancaria
class Banca {
    int total = 100;
    void withdrawn(String name, int withdrawal)
    {
        if (total >= withdrawal) {
            System.out.println(name + " retiró "
                    + withdrawal);
            total = total - withdrawal;
            System.out.println(total);
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // Else if the money requested for withdrawal is
        // greater than the balance then deny transaction
        else {
            System.out.println(name
                    + " no puedes retirar "
                    + withdrawal);
            System.out.println("Tu saldo es: " + total);
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    void deposit(String name, int deposit)
    {
        System.out.println(name + " depositó " + deposit);
        total = total + deposit;
        System.out.println("Saldo después del depósito: "
                + total);
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// Método - Método de retiro
// Llamada desde la clase ThreadWithdrawal
// utilizando el objeto de la clase Banca pasado
// desde el método main()
class ThreadWithdrawal extends Thread {
    Banca object;
    String name;
    int dollar;
    // Constructor de esta clase
    ThreadWithdrawal(Banca ob, String name, int money)
    {
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
    // método run() para el hilo
    public void run() { object.withdrawn(name, dollar); }
}
// El método Deposit se llama desde la clase ThreadDeposit
// utilizando el objeto de la clase Banca
// pasado desde el método main
class ThreadDeposit extends Thread {
    Banca object;
    String name;
    int dollar;
    ThreadDeposit(Banca ob, String name, int money)
    {
        // La palabra clave "this" se refiere a la propia instancia actual
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
    public void run() { object.deposit(name, dollar); }
}
// Clase Principal
class GFG {
    // Metodo Main
    public static void main(String[] args)
    {
        // Declarar un objeto de la clase Banca y pasar el objeto
        // junto con otros parámetros a la clase ThreadWithdrawal
        // y ThreadDeposit. Esto será necesario para llamar
        // a los métodos withdrawn y deposit
        // de esas clases
        // Creación de un objeto de la clase Banca
        Banca obj = new Banca();
        ThreadWithdrawal t1
                = new ThreadWithdrawal(obj, "Alex", 20);
        ThreadWithdrawal t2
                = new ThreadWithdrawal(obj, "Mónica", 40);
        ThreadDeposit t3
                = new ThreadDeposit(obj, "Martha", 35);
        ThreadWithdrawal t4
                = new ThreadWithdrawal(obj, "Ronald", 80);
        ThreadWithdrawal t5
                = new ThreadWithdrawal(obj, "Santiago", 40);
        // Cuando un programa llama al método start(),
        // se crea un nuevo hilo y
        // luego se ejecuta el método run()
        // Inicio de los hilos creados anteriormente
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Salida:

Santiago retiró 40
60
Martha depositó 35
Alex retiró 20
75
Ronald retiró 80
-5
Mónica retiró 40
-45
Saldo después del depósito: 95
Ejemplo 2 de operación bancaria en Java
Ejemplo 2 de operación bancaria en Java

Ahora hay ciertos problemas con el enfoque multihilo como se indica a continuación:

Cuando varios hilos tratan de hacer una operación particular al mismo tiempo, existe la posibilidad de una mala salida, esto es porque todos los hilos están actualizando el mismo recurso a la vez. En la salida anterior, obtuvimos un balance en cifras negativas debido a la misma razón.

¿Cómo manejar esos casos en los que varias personas intentan acceder a la misma operación a la vez?

Si varios hilos acceden a un mismo recurso a la vez, existe la posibilidad de que la salida sea mala. Este fenómeno no deseado se define como carrera de datos (data racing).

Supongamos que tenemos 100 dólares en nuestra cuenta bancaria conjunta. Para engañar al banquero, ambos podemos solicitar 100 dólares simultáneamente a la vez. El sistema creará un objeto, asignará 2 hilos y los pasará al método de retirada. Al final del proceso, ambos tendremos 100 dólares.

Para solucionar este problema, los ingenieros han creado el concepto de sincronización.

Método 3: Incorporar la Sincronización con el MultiHilo

La sincronización proporciona un bloqueo al objeto y declara un área sensible (métodos de retirada y depósito). Un objeto puede tener múltiples hilos, pero el área sensible sólo puede ser accedida por un hilo a la vez. El programador de hilos elige el orden de ejecución de los hilos. Como es un proceso aleatorio la salida es diferente para cada interpretación.

¿Por qué debemos utilizar la sincronización estática?

Digamos que tenemos 5 clases de hilos con 1 objeto cada una. Cada objeto tiene múltiples hilos. ¡Ahora el área sensible será accedida por 5 hilos a la vez! Para manejar este problema, los ingenieros tuvieron la idea de la sincronización estática. Proporcionamos un bloqueo a la clase. La clase seleccionará 1 objeto a la vez. El objeto a su vez elegirá 1 hilo y lo pasará por la zona sensible.

¿La ejecución multihilo sincronizada es más lenta que la ejecución normal sin multihilo?

No. La cantidad de tiempo que una tarea pasa esperando a otra se considera como sobrecarga. En el multihilo sincronizado, este tiempo de sobrecarga se puede utilizar para realizar otro trabajo productivo hasta que el hilo de espera obtenga la clave del programador de hilos para entrar en el área sincronizada. Así, la sobrecarga sería mínima en el caso de la ejecución multihilo sincronizada, por lo que podemos esperar que sea más rápida.

Código Fuente:

// Programa Java para ilustrar el sistema de transacciones bancarias
// Clase Banca
// Definición de la operación bancaria
class Banca {
    //Saldo inicial $100
    static int total = 100;
    static synchronized void withdrawn(String name,
                                       int withdrawal)
    {
        if (total >= withdrawal) {
            System.out.println(name + " retiró "
                    + withdrawal);
            total = total - withdrawal;
            System.out.println("Saldo después del retiro: "
                    + total);
            /* Hacer que el hilo duerma durante 1 segundo después de
                 cada retiro.*/
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // Si el dinero solicitado para retirar es mayor
        // que el saldo, entonces deniega la transacción
        else {
            System.out.println(name
                    + " no puedes retirar "
                    + withdrawal);
            System.out.println("Tu saldo es: " + total);
            // Hacer que el hilo duerma durante 1 segundo después de
            //   cada fallo de transacción
            // Bloque Try para comprobar las excepciones
            try {
                // Hacer que el hilo duerma durante 1 segundo
                Thread.sleep(1000);
            }
            // Bloque catch para manejar excepciones
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    // Método de depósito
    // Aceptar dinero siempre que se deposite
    static synchronized void deposit(String name,
                                     int deposit)
    {
        System.out.println(name + " depositó " + deposit);
        total = total + deposit;
        System.out.println("Saldo después del depósito: "
                + total);
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// Método - Método de retiro
// Llamada desde la clase ThreadWithdrawal
// utilizando el objeto de la clase Banca pasado
// desde el método main()
class ThreadWithdrawal extends Thread {
    Banca object;
    String name;
    int dollar;
    // Constructor de esta clase
    ThreadWithdrawal(Banca ob, String name, int money)
    {
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
    // método run() para el hilo
    public void run() { object.withdrawn(name, dollar); }
}
// El método Deposit se llama desde la clase ThreadDeposit
// utilizando el objeto de la clase Banca
// pasado desde el método main
class ThreadDeposit extends Thread {
    Banca object;
    String name;
    int dollar;
    ThreadDeposit(Banca ob, String name, int money)
    {
        // La palabra clave "this" se refiere a la propia instancia actual
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
    public void run() { object.deposit(name, dollar); }
}
// Clase Principal
class GFG {
    // Metodo Main
    public static void main(String[] args)
    {
        // Declarar un objeto de la clase Banca y pasar el objeto
        // junto con otros parámetros a la clase ThreadWithdrawal
        // y ThreadDeposit. Esto será necesario para llamar
        // a los métodos withdrawn y deposit
        // de esas clases
        // Creación de un objeto de la clase Banca
        Banca obj = new Banca();
        ThreadWithdrawal t1
                = new ThreadWithdrawal(obj, "Alex", 20);
        ThreadWithdrawal t2
                = new ThreadWithdrawal(obj, "Mónica", 40);
        ThreadDeposit t3
                = new ThreadDeposit(obj, "Martha", 35);
        ThreadWithdrawal t4
                = new ThreadWithdrawal(obj, "Ronald", 80);
        ThreadWithdrawal t5
                = new ThreadWithdrawal(obj, "Santiago", 40);
        // Cuando un programa llama al método start(),
        // se crea un nuevo hilo y
        // luego se ejecuta el método run()
        // Inicio de los hilos creados anteriormente
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Salida:

Alex retiró 20
Saldo después del retiro: 80
Santiago retiró 40
Saldo después del retiro: 40
Ronald no puedes retirar 80
Tu saldo es: 40
Martha depositó 35
Saldo después del depósito: 75
Mónica retiró 40
Saldo después del retiro: 35
Ejemplo 3 de operación bancaria en Java
Ejemplo 3 de operación bancaria en Java

El programador de hilos elige el orden de ejecución de los hilos. Como es un proceso aleatorio, la salida es diferente para cada interpretación.

En resumen, este ejemplo de código fuente ilustra un sencillo programa Java utilizado en el sector bancario. Espero que los ejemplos básicos de transacción bancaria en Java te proporcionen los fundamentos básicos de cómo implementar algunas operaciones relacionadas.

Sobre el Autor:

Hey hola! Yo soy Alex Walton y tengo el placer de compartir conocimientos hacía ti sobre el tema de Programación en Java, desde cero, Online y Gratis.

Deja una Respuesta

*

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.