任务:帐户表(帐户号,姓名,余额,锁定)。实现帐号1向帐号2转账若干元。 业务要求 1、两个帐户要存在(略) 2、转账方最低余额为10元 3、如果任何一方被锁定(u_lock=1),则不能转 4、要保证交易完整性(不能一个成功,一个失败) create table T_ACCOUNT ( U_ID NUMBER(5) primary key, U_NAME VARCHAR2(100) not null, U_MONEY NUMBER(7) not null, U_LOCK NUMBER(1) default 0 ); insert into T_ACCOUNT (U_ID, U_NAME, U_MONEY, U_LOCK) values (1, '张三', 900, 0); insert into T_ACCOUNT (U_ID, U_NAME, U_MONEY, U_LOCK) values (2, '李四', 100, 0); insert into T_ACCOUNT (U_ID, U_NAME, U_MONEY, U_LOCK) values (3, '杨五郎', 3000, 1); commit;
public void transMoney() throws Exception{ //操作数据库(业务上的连接对象) Connection conn = DBUtil.getNewConn(); //try捕捉的是SQL异常 try { conn.setAutoCommit(false); dao.setConn(conn); poFrom = dao.getpAccountPo(poFrom.getId()); poTo = dao.getpAccountPo(poTo.getId()); System.out.println("查询账户完成,请稍侯..."); new Scanner(System.in).nextLine(); if(poFrom==null || poTo==null){ throw new Exception("帐户不存在!"); } else if(poTo.getLock()==1 || poFrom.getLock()==1){ throw new Exception("帐户已被锁定!"); } else if(poFrom.getMoney()-this.money<10){ throw new Exception("帐户余额不足!"); } //转账 this.poFrom.setMoney(this.poFrom.getMoney()-this.money); this.poTo.setMoney(this.poTo.getMoney()+this.money); dao.updateMoney(poFrom); dao.updateMoney(poTo); //演示:某数据被修改以后不能再被其它用户修改 System.out.println("确定转账吗(1-确定;其它-取消)?"); int ok = new Scanner(System.in).nextInt(); if(ok==1){ dao.getConn().commit(); conn.setAutoCommit(true); System.out.println("恭喜,转账成功!"); }else{ dao.getConn().rollback(); System.out.println("用户取消操作!"); } } catch (SQLException e1) { try { dao.getConn().rollback(); System.out.println("出错回滚啦!"+e1.getMessage()); } catch (SQLException e) { e.printStackTrace(); } }finally{ DBUtil.closeConn(dao.getConn()); } }
create or replace procedure sp_trans_money ( p_from number, p_to number, p_money NUMBER ) is v_count number; v_lock number; v_money number; begin --to是否存在 select count(*) into v_count from t_account where u_id = p_to; if v_count = 0 then raise_application_error(-20087, '目标用户不存在!'); end if; --to是否锁定 select u_lock into v_lock from t_account where u_id = p_to; if v_lock = 1 then raise_application_error(-20088, '该用户已锁定!'); end if; --from是否存在 select count(*) into v_count from t_account where u_id = p_from; if v_count = 0 then raise_application_error(-20087, '转账用户不存在!'); end if; --from是否锁定及余额 select u_lock, u_money into v_lock, v_money from t_account where u_id = p_from; if v_lock = 1 then raise_application_error(-20088, '该用户已锁定!'); elsif (v_money - p_money < 10) then raise_application_error(-20089, '该用户余额不足!'); end if; update t_account set u_money = u_money - p_money where u_id = p_from; update t_account set u_money = u_money + p_money where u_id = p_to; --通常是由存储过程提交事务 --如果存储过程不提交,则由调用方提交事务 --好处:可以将多个存储过程放在一个事务中,但通常一个存储过程就是处理一个单独的事务,所以在实际开发中,具体情况具体处理 --commit; end;