面试题答案
一键面试场景设计
假设我们有一个银行转账的场景,从一个账户向另一个账户转账一定金额。这涉及到两个数据库操作:从转出账户减去相应金额,向转入账户增加相应金额。为了确保数据的一致性和完整性,需要使用事务管理。同时,在操作过程中可能会出现各种异常,比如账户不存在、余额不足、数据类型不匹配等,需要进行全面的异常处理。
实现方案
- 开启事务:在函数开始时,使用
START TRANSACTION
语句开启一个事务。 - 执行数据库操作:执行转出账户减款和转入账户加款的SQL语句。
- 异常处理:使用
DECLARE EXIT HANDLER
声明异常处理程序,捕获可能出现的异常。 - 回滚事务:如果捕获到异常,使用
ROLLBACK
语句回滚事务,确保数据的一致性。 - 返回错误信息:通过设置用户定义变量,将有意义的错误信息返回给调用者。
SQL 代码
-- 创建函数
DELIMITER //
CREATE FUNCTION transfer_funds(
from_account_id INT,
to_account_id INT,
amount DECIMAL(10, 2)
) RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
DECLARE error_message VARCHAR(255);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 捕获异常,回滚事务
ROLLBACK;
-- 设置错误信息
SET error_message = '操作过程中出现错误';
RETURN error_message;
END;
-- 开启事务
START TRANSACTION;
-- 检查转出账户余额是否足够
IF (SELECT balance FROM accounts WHERE account_id = from_account_id) < amount THEN
SET error_message = '转出账户余额不足';
ROLLBACK;
RETURN error_message;
END IF;
-- 执行转出操作
UPDATE accounts SET balance = balance - amount WHERE account_id = from_account_id;
-- 执行转入操作
UPDATE accounts SET balance = balance + amount WHERE account_id = to_account_id;
-- 提交事务
COMMIT;
-- 返回成功信息
RETURN '转账成功';
END //
DELIMITER ;
说明
- 函数定义:定义了一个名为
transfer_funds
的函数,接受三个参数:转出账户ID、转入账户ID和转账金额。 - 异常处理程序:使用
DECLARE EXIT HANDLER FOR SQLEXCEPTION
捕获所有SQL异常,在异常发生时回滚事务并设置通用错误信息。 - 余额检查:在执行转账操作前,检查转出账户余额是否足够,若不足则回滚事务并返回相应错误信息。
- 事务操作:使用
START TRANSACTION
开启事务,UPDATE
语句执行转账操作,最后使用COMMIT
提交事务。若整个过程无异常,返回成功信息。若出现异常,事务回滚并返回错误信息给调用者。