为了保持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();
}
}
}
数据库格式