Lab4
Lab4
In this lab, you will continue building on the bank database by integrating advanced transaction
management and loan assessment functionalities. This involves creating procedures for essential
banking operations—such as depositing, transferring, and withdrawing money—and designing a
comprehensive loan assessment system. You will utilize a previously developed loan assessment
function to determine if a person is eligible for a loan and the maximum loan they can receive.
Objective: Develop three procedures to handle core banking transactions, with appropriate
logging and validation mechanisms.
• Objective: Create a trigger that prevents any updates that would lead to a negative
balance.
• Trigger: Use an AFTER UPDATE trigger to check if a balance becomes negative during
a transaction. If so, roll back the transaction and raise an error.
1
Solution.
DESCRIBE accounts ;
DESCRIBE operations ;
Creating Procedures
DELIMITER //
CREATE PROCEDURE dep_proc(
IN acc_num varchar(50) ,
IN deposit_amount double
)
BEGIN
-- Update account balance
UPDATE person
SET balance = balance + ABS(deposit_amount)
WHERE account_number = acc_num;
-- branch name
set @branch_name = (SELECT branch_name FROM person WHERE account_number =
acc_num );
DELIMITER //
CREATE PROCEDURE tran_proc(
IN source_acc varchar(50) ,
IN target_acc varchar(50) ,
IN transfer_amount double
2
)
BEGIN
-- branch name
set @branch_name = (SELECT branch_name FROM person WHERE account_number =
source_acc );
DELIMITER //
CREATE PROCEDURE wid_proc(
IN acc_num varchar(50) ,
IN deposit_amount double
)
BEGIN
-- Update account balance
UPDATE person
SET balance = balance - ABS(deposit_amount)
WHERE account_number = acc_num;
-- branch name
set @branch_name = (SELECT branch_name FROM person WHERE account_number =
acc_num );
3
INSERT INTO operations (account_number, operation_type,
branch_name,amount, operation_time,target_account_number)
VALUES (acc_num, 'withdraw', @branch_name,ABS(deposit_amount),
NOW(),acc_num);
END //
DELIMITER ;
DELIMITER //
CREATE TRIGGER balance_check_trigger
BEFORE UPDATE ON person
FOR EACH ROW
BEGIN
-- Check if the new balance is negative
IF NEW.balance < 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Error: Balance cannot be negative.';
END IF;
END //
DELIMITER ;
Verification:
4
Part 2: Loan Management System
1. Function: loan_eligibility
o Input: account_number, requested_loan_amount.
o Output: Returns either the maximum loan amount that can be approved or a
denial message.
2. Criteria:
o Individual Eligibility: The person should have a minimum balance threshold
(you may define a logical threshold, e.g., 10% of the requested loan amount).
o Bank Capacity: The loan should not exceed a specific percentage of the
bank's total assets. Set a reasonable limit, such as 20% of the total balance
held in the bank.
1. Procedure: loan_proc
o Input: account_number, requested_loan_amount.
o Action:
▪ Use the loan_eligibility function to evaluate if the requested loan
is feasible.
▪ If the loan is approved, increase the account's balance by the approved
loan amount.
▪ Log the loan approval or denial in the operations table.
2. Implementation:
o Call the loan_eligibility function within the procedure.
o If approved, execute the deposit of the loan amount into the customer’s
account.
o If denied, provide an appropriate message explaining the reason.
Solution.
Before we begin, if this was our first time developing a stored function in MySQL, we
need to check a global variable and change its values to 1 if it turns out to be 0, and that is:
This variable applies when binary logging is enabled and it controls whether stored function
creators can be trusted not to create stored functions that may cause unsafe events to be written
to the binary log.
5
If set to 0 (the default), users are not permitted to create or alter stored functions unless they
have the SUPER privilege. A setting of 0 also enforces the restriction that a function must be
declared with the DETERMINISTIC characteristic. If the variable is set to 1, MySQL does
not enforce these restrictions on stored function creation.
DELIMITER //
CREATE FUNCTION loan_eligibility(
acc_number varchar(50),
requested_loan_amount double
) RETURNS VARCHAR(255)
NOT DETERMINISTIC
BEGIN
DECLARE individual_balance double;
DECLARE total_bank_balance double;
DECLARE min_required_balance double;
DECLARE max_loan_amount double;
DECLARE result_message VARCHAR(255);
-- Get the total balance of the bank, attention not to use the information
from the table person. Here, I used the information from the table operations
SELECT (Deposit - Withdraw) INTO total_bank_balance FROM
(SELECT SUM(amount) as Deposit FROM operations WHERE operation_type =
'deposit' ) as a,
(SELECT SUM(amount) as Withdraw FROM operations WHERE operation_type =
'withdraw' ) as b;
RETURN result_message;
END //
6
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE loan_proc(
IN acc_num varchar(50),
IN requested_loan_amount double
)
BEGIN
DECLARE eligibility_message VARCHAR(255);
DECLARE approved_amount double;
-- branch name
set @branch_name = (SELECT branch_name FROM person WHERE account_number =
acc_num );
SELECT eligibility_message ;
ELSE
SELECT eligibility_message ;
END IF;
END $$
DELIMITER ;
7
Verification: Test the procedure by calling:
Overview:
In a real-world banking environment, multiple users might interact with the database
simultaneously. To handle such situations effectively, it is crucial to understand and implement
concurrency control mechanisms, such as locks and transaction isolation levels. These
mechanisms will help maintain data consistency and integrity, ensuring that concurrent
transactions do not interfere with one another.
Objective: Learn to use locks to ensure data consistency during concurrent transactions,
particularly for critical operations like money transfers.
1. Table-Level Locking:
o Implement table-level locks when accessing shared resources, like modifying
account balances.
o Example:
▪ Use LOCK TABLES accounts WRITE before performing multiple
account updates to ensure exclusive access.
▪ Release the lock with UNLOCK TABLES after completing the operation.
2. Row-Level Locking:
o Implement row-level locks for greater granularity, allowing more
concurrency.
o Use the SELECT ... FOR UPDATE statement to lock specific rows during a
transfer, withdrawal, or deposit operation.
o Example:
▪ Lock an account’s row when updating its balance, ensuring no other
transaction can modify the same row until the operation completes.
Objective: Explore how different isolation levels impact the visibility of transactions and the
potential for conflicts in a multi-user environment.
8
oRead Committed: Transactions only see changes that have been committed
(no dirty reads allowed).
o Repeatable Read: Transactions see a consistent view of the database from the
start of the transaction (no non-repeatable reads).
o Serializable: Transactions are completely isolated from each other, behaving
as if they were executed sequentially.
2. Exercise:
Procedure Adjustment:
o Modify the tran_proc to use Repeatable Read isolation, ensuring that the
balance remains consistent during a transfer.
o Apply a Serializable level to the loan procedure to avoid issues with
concurrent loan assessments.
Testing:
Solution.
• Any tables related by a foreign key constraint are opened and locked implicitly.
• Any tables used in triggers are also locked implicitly.
• A session holding a WRITE lock can perform table-level operations such as DROP
TABLE or TRUNCATE TABLE.
• For sessions holding a READ lock, DROP TABLE and TRUNCATE TABLE
operations are not permitted.
UNLOCK TABLES ;
9
• Any lock placed with the `FOR UPDATE` will not allow other transactions to read,
update or delete the row.
• Any lock placed with `FOR SHARE ` will allow other transaction to read the locked
row but it will not allow other transaction to update or delete the row.
Procedure Adjustment:
o Modify the tran_proc to use Repeatable Read isolation, ensuring that the
balance remains consistent during a transfer.
Solution.
Nothing to do here, since the Repeatable Read is the default isolation mode in innodb.
DELIMITER $$
CREATE PROCEDURE loan_proc(
IN acc_num varchar(50),
IN requested_loan_amount double
)
BEGIN
DECLARE eligibility_message VARCHAR(255);
DECLARE approved_amount double;
10
-- Update the account's balance
UPDATE person SET balance = balance + approved_amount
WHERE account_number = account_number;
SELECT eligibility_message ;
ELSE
SELECT eligibility_message ;
END IF;
-- Commit the transaction
COMMIT;
END $$
DELIMITER ;
11