JAVA-WEB 事务 - 使用ThreadLocal绑定连接资源

JAVA-WEB 事务

为了保持javaee三层结构,service层中用的开启事务,rollback,以及commit被封装在了utils中

web层servlet

package web;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import domain.Account;
import service.AccountService;
public class AccountTransfor extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		AccountService as = new AccountService();
		response.setContentType("text/html; charset=UTF-8");
		//获得转账账户与金额
		Account out = null;
		Account in = null;
		try {
			out = as.getAccount("alex");
			in = as.getAccount("alex1");
		} catch (SQLException e) {
			e.printStackTrace();
		}

		double money = 500;
//		System.out.println(out);
//		System.out.println(in);
		//调用服务层方法

		boolean b = as.accountTransfer(out, in, money);
		if(b==true) {
			response.getWriter().println("转账成功");
		}else {
			response.getWriter().println("转账失败");
		}
		
		
		
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}


service层

package service;

import java.sql.SQLException;

import domain.Account;
import utils.C3P0Utils;

public class AccountService {

	public boolean accountTransfer(Account out, Account in, double money) {
		//调用DAO层的方法
		AccountDao adao = new AccountDao();
		boolean isTransfer = false;
		try {
			//开启事务
			C3P0Utils.startTranscion();
			int row = adao.transferOut(out, money);
//			int i = 1/0;//模拟故障
			int row1 = adao.transferIn(in, money);
			isTransfer = true;
		} catch (SQLException e) {
			try {
				C3P0Utils.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally {
			try {
				C3P0Utils.commit();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return isTransfer;
	}

	public Account getAccount(String name) throws SQLException {
		AccountDao adao = new AccountDao();
		Account account = adao.getAccount(name);
		return account;
	}

	

}


DAO层

package service;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import domain.Account;
import utils.C3P0Utils;

public class AccountDao {
	/*
	 * 转出
	 */
	public int transferOut(Account out, double money) throws SQLException {
		//获得现有链接
		Connection conn = C3P0Utils.getCurrentConnection();
		//获得QueryRunner对象
		QueryRunner qr = new QueryRunner();
		String sql = "update account set money=money-? where name=? and id=?";
		int row = qr.update(conn, sql, money, out.getName(), out.getId());
		return row;
	}
	/*
	 * 转入
	 */
	public int transferIn(Account in, double money) throws SQLException {
		//获得现有链接
		Connection conn = C3P0Utils.getCurrentConnection();
		//获得QueryRunner对象
		QueryRunner qr = new QueryRunner();
		String sql = "update account set money=money+? where name=? and id=?";
		int row = qr.update(conn, sql, money, in.getName(), in.getId());
		return row;
	}
	
	
	public Account getAccount(String name) throws SQLException {
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "select * from account where name=?";
		return qr.query(sql, new BeanHandler<Account>(Account.class), name);
	}

}

Utils

package com.demo.fenye.utils;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/*
 * C3P0工具类
 */
public class C3P0Utils {
    private static DataSource dataSource = new ComboPooledDataSource("c3p0-config");
    //获得ThreadLocal对象,用来在进程中存储数据
    private static ThreadLocal<Connection> tl = new ThreadLocal<>();
    
    public static void rollback() throws SQLException {
        getCurrentConnection().rollback();
    }
    
    public static void startTranscion() throws SQLException {
        getCurrentConnection().setAutoCommit(false);
    }
    
    public static Connection getCurrentConnection() {

        //从进程中获得Connection对象
        Connection conn = tl.get();
        //判断conn对象是否为空
        if(conn == null) {
            //getConnection()从方法获得conn;
            conn = getConnection();
            //存入tl对象中
            tl.set(conn);
        }
        //直接返回conn
        return conn;
    }
    
    
    public static DataSource getDataSource() {
        //返回资源池
        return dataSource;
    }
    
    public static Connection getConnection() {
        //返回Connection
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        
    }

    public static void commit() throws SQLException {
        Connection conn = getCurrentConnection();
        if(conn != null) {
            conn.commit();
            conn.close();
            tl.remove();
        }
    }
    
    
    
    

}


数据库格式


猜你喜欢

转载自blog.csdn.net/alexzt/article/details/80926062