JAVA事务回滚

        当一个租赁系统在租房服务时我们会判断用户的账户金额是否够支付本次的房费,如果钱够则扣款,在订单表插入一条本次业务相关的数据,这时候如果在订单表插入出现了异常,但是钱已经扣款成功了,这样的情况就可以加入事务回滚。

       事务回滚将本次的操作都使用同一个Connection进行操作,于是加入了ThreadLocal存放Connection

        在获取Connection时先看一下当前ThreadLocal是否存放有Connection,如果有则直接从里面获取,没有的话就创建一个Connection并将其放入ThreadLocal中,本次业务中就直接往里取。

private static ThreadLocal threadLocal = new ThreadLocal();
public static Connection getConnection(){
        try {
            //在ThreadLocal获取Connection
            conn = (Connection) threadLocal.get();
            //如果没有获取到则进入
            if (conn==null){
                conn = DriverManager.getConnection(url, user, password);
                //将新建的Connection保存到ThreadLocal中
                threadLocal.set(conn);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

       销毁时则是下图调用closeAll时将Connection传进去。

public static void closeAll(Connection conn, Statement st, ResultSet rs) {
        try {
                if (rs != null){
                    rs.close();
                }
                if (st != null){
                    st.close();
                }
                if (conn != null){
                    conn.close();
                    threadLocal.remove();
                }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

        将Connection对象设置使用setAutoCommit(false)方法设置手动提交事务,接着进行具体业务的操作,如下判断钱是否够、钱够退款、扣款成功添加订单,底层异常往上抛,如果没有出现异常时就提交事务,出现异常时捕获到则回滚事务,业务结束后调用closeAll把Connection对象关闭,并清除了ThreadLocal里的Connection对象;

Connection conn = DBUtil.getConnection();
        try{
            conn.setAutoCommit(false);//开始手动提交事务
            //具体操作
            //判断用户钱是否足够
            //钱够则扣款
            //扣款成功后添加订单
            conn.commit(); //提交事务
        }catch (Exception ex){
            ex.printStackTrace();
            conn.rollback(); //事务回滚
        }finally {
            DBUtil.closeAll(conn,null,null);
        }

        因为其他业务处理时也要使用到事务回滚,可将事务回滚部分封装代理模式

package com.bjpwoernode.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class Agent implements InvocationHandler {
    private Object service;

    public Agent(Object service){
        this.service = service;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        Connection conn = DBUtil.getConnection();
        try{
            conn.setAutoCommit(false);
            result = method.invoke(service,args); 
            conn.commit();
        }catch (Exception ex){
            ex.printStackTrace();
            conn.rollback();
        }finally {
            DBUtil.closeAll(conn,null,null);
        }
        return result;
    }

    public Object getAgent(){
        Object lisi = Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), this);
        return lisi;
    }
}
package com.bjpwoernode;

import com.bjpwoernode.model.Order;
import com.bjpwoernode.service.rentingHouseService;
import com.bjpwoernode.service.serviceImpl.rentingHouseServiceImpl;
import com.bjpwoernode.util.Agent;

import java.lang.reflect.InvocationHandler;
import java.sql.SQLException;

public class MainTest {
    public static void main(String[] args) {

        Order order = new Order();
        order.setuID(3);
        order.sethID(2);
        rentingHouseService rentingHouseService = new rentingHouseServiceImpl();
        InvocationHandler agentManager = new Agent(rentingHouseService);
        rentingHouseService lisi = (rentingHouseService) ((Agent)agentManager).getAgent();
        try {
           int flag = lisi.rentingHouse(order,1300,2);
           if (flag == 1)
               System.out.println("租赁成功");
           if (flag == 0)
               System.out.println("权限不足");
           if(flag == -1)
               System.out.println("金币不足请充值");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值