转账汇款案例

垃圾版代码,只提供一个思路

第一个版本

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'index.jsp' starting page</title>

</head>

<body>
    <form action="${pageContext.request.contextPath}/account" method="post">
        转款人<input type="text" name="outuser"> 收款人<input type="text"
            name="inuser"> 金额<input type="text" name="money"> <input
            type="submit" value="转账">
    </form>
</body>
</html>

servlet

public class AccountServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        // 1.收集数据
        String outuser = request.getParameter("outuser");
        String inuser = request.getParameter("inuser");
        String money = request.getParameter("money");

        // 2.调用AccountService中的account方法

        AccountService service = new AccountService();

        try {
            service.account(outuser, inuser, money);

            response.getWriter().write("汇款成功");
        } catch (AccountException e) {
            e.printStackTrace();
            response.getWriter().write(e.getMessage());
        }

    }

}

service

public class AccountService {
    // 原始转账方法
    public void _account(String outuser, String inuser, String money)
            throws AccountException {
        AccountDao dao = new AccountDao();

        // 获取连接对象,并开启事务
        Connection con = null;

        try {
            con = JdbcUtils.getConnection();
            con.setAutoCommit(false); // 开启事务
            // 调用AccountDao中两个方法
            // 转出
            dao.accountOut(con, outuser, money);
            // 转入
            dao.accountIn(con, inuser, money);
        } catch (SQLException e) {
            e.printStackTrace();
            // 事务回滚
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            throw new AccountException("转账失败");
        } catch (AccountException e) {
            e.printStackTrace();
            // 事务回滚
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            throw e;
        } finally {

            try {
                con.commit(); // 提交事务
                con.close(); // 关闭资源
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 转账方法
    public void account(String outuser, String inuser, String money)
            throws AccountException {
        AccountDao dao = new AccountDao();

        try {
            // 开启事务
            JdbcUtils.startTransaction();
            // 转出
            dao.accountOut(outuser, money);
            // 转入
            dao.accountIn(inuser, money);
        } catch (SQLException e) {
            e.printStackTrace();
            // 事务回滚
            try {
                JdbcUtils.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            throw new AccountException("转账失败");
        } catch (AccountException e) {
            e.printStackTrace();
            // 事务回滚
            try {
                JdbcUtils.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            throw e;
        } finally {

            try {
                JdbcUtils.commit();// 提交事务
                JdbcUtils.closeConnection(); // 关闭资源
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

dao

public class AccountDao {

    // 转入
    public void accountIn(Connection con, String inuser, String money)
            throws SQLException, AccountException {
        String sql = "update account set money=money+? where username=?";

        PreparedStatement pst = con.prepareStatement(sql);
        pst.setString(1, money);
        pst.setString(2, inuser);

        int row = pst.executeUpdate();
        if (row == 0) {
            throw new AccountException("转入失败");
        }
        pst.close();
    }

    // 转出
    public void accountOut(Connection con, String outuser, String money)
            throws SQLException, AccountException {

        String sql = "update account set money=money-? where username=?";
        PreparedStatement pst = con.prepareStatement(sql);
        pst.setString(1, money);
        pst.setString(2, outuser);

        int row = pst.executeUpdate();
        if (row == 0) {
            throw new AccountException("转出失败");
        }
        pst.close();
    }

    // 转入--使用ThreadLocal获取连接
    public void accountIn(String inuser, String money) throws SQLException,
            AccountException {
        Connection con = JdbcUtils.getConnection();
        String sql = "update account set money=money+? where username=?";

        PreparedStatement pst = con.prepareStatement(sql);
        pst.setString(1, money);
        pst.setString(2, inuser);

        int row = pst.executeUpdate();
        if (row == 0) {
            throw new AccountException("转入失败");
        }
        pst.close();
    }

    // 转出
    public void accountOut(String outuser, String money) throws SQLException,
            AccountException {
        Connection con = JdbcUtils.getConnection();
        String sql = "update account set money=money-? where username=?";
        PreparedStatement pst = con.prepareStatement(sql);
        pst.setString(1, money);
        pst.setString(2, outuser);

        int row = pst.executeUpdate();
        if (row == 0) {
            throw new AccountException("转出失败");
        }
        pst.close();
    }
}

exception

public class AccountException extends Exception {

    public AccountException() {
        super();
    }

    public AccountException(String message, Throwable cause) {
        super(message, cause);
    }

    public AccountException(String message) {
        super(message);
    }

    public AccountException(Throwable cause) {
        super(cause);
    }

}
//高级的,使用ThreadLocal
public class JdbcUtils {

    private static final String DRIVERCLASSNAME;
    private static final String URL;
    private static final String USER;
    private static final String PASSWORD;

    static {
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        DRIVERCLASSNAME = bundle.getString("DRIVERCLASSNAME");
        URL = bundle.getString("URL");
        USER = bundle.getString("USER");
        PASSWORD = bundle.getString("PASSWORD");
    }

    static {
        try {
            Class.forName(DRIVERCLASSNAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); // 它就相当于是一个Map集合。

    public static Connection getConnection() throws SQLException {

        // Connection con = tl.get(); // 从ThreadLocal中获取,第一次一得到的一定是null.
        // if (con == null) {
        Connection con = DriverManager.getConnection(URL, USER, PASSWORD);
        // tl.set(con);// 将con装入到ThreadLocal中。
        // }
        return con;
    }

    // 封装事务操作.
    // 开启事务
    public static void startTransaction() throws SQLException {
        Connection con = getConnection();
        con.setAutoCommit(false);
    }

    public static void rollback() throws SQLException {
        Connection con = getConnection();
        con.rollback();
    }

    // 事务提交
    public static void commit() throws SQLException {
        Connection con = getConnection();
        con.commit();
    }

    public static void closeStatement(Statement st) throws SQLException {
        if (st != null)
            st.close();
    }

    public static void closeResultSet(ResultSet rs) throws SQLException {
        if (rs != null)
            rs.close();
    }

 

ThreadLocal

它的底层是使用了一个Map集合

Map<Thread,Object>

它的key就是当前的线程对象.

set(Object obj) 它就相当于  map.put(Thread.currentThread(),obj);

get()它就相当于 map.get(Thread.currentThread()));

原文地址:https://www.cnblogs.com/MessiAndDream/p/6072155.html