栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA事务回滚

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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();
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/292692.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号