javaWeb事务

JDBC事务: 

  cmd 命令上的事务开启:  start transaction;   /  begin;

     回滚   rollback;

      提交    commit;

   

JDBC事务控制:

    开启事务:conn.setAutoCommit(false);

    提交:conn.commit();

    回滚:conn.rollback();

DBUtils的事务控制 也是通过jdbc

 

ThreadLocal:实现的是通过线程绑定的方式传递参数

 

 

事务回滚后 ,一定要commit  才能算这个事务完成

 

 

 

 

 jdbc事务的运用  

form 提交表单

<fieldset>
            <legend> 转账</legend>
            <form action="${pageContext.request.contextPath}/transferServlet" method="post">
            转出账户:<input type="text" name="outName"><br/><br>
            转入账户:<input type="text" name="inName"><br><br>
            转账金额 :<input type="text" name="money"><br/><br>
            <input type="submit"  value="确定">
        
            </form>
    </fieldset>

web 层 servlet   doGet 和doPost 方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String inName=request.getParameter("inName");
        String outName=request.getParameter("outName");
        String moneystr=request.getParameter("money");
        double money=Double.parseDouble(moneystr);
        //调用service层的方法
        TransferService transfer=new TransferService();
        boolean falg = transfer.transfermoney(inName,outName,money);
        if (falg) {
            response.getWriter().write("转账成功");
        }else {
            response.getWriter().write("转账失败");
        }
    }

    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }

service 层类:

package com.study.transfer.service;

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

import com.study.transfer.dao.TransferDao;
import com.study.util.C3P0Utils;

public class TransferService {
 
    public boolean transfermoney(String inName, String outName, double money) {
        //调用dao层的inMoney 和  outMoney 
        
        TransferDao dao=new TransferDao();
        Connection conn=null;
        //dao 层 的conn 
        //jdbc事务的处理 conn SQL语句的执行 和事务的提交,回滚需要时同一个conn;
        boolean isTransfer=true;
        int number1=-1;
        int number2=-1;
        try {
//缺点是 出现了dao层的conn连接 , 
            conn=C3P0Utils.getConnection();
            conn.setAutoCommit(false);
            number1=dao.inMoney(conn,inName ,money);
//            int a=1/0;
            number2=dao.outMoney(conn,outName,money);
            if (number1==-1 || number2==-1) {
                //当sql语句的任何一条没有执行成功,就回滚的初始状态
                conn.rollback();
            }
        } catch (Exception e) {
            isTransfer=false;
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally{
            try {
                conn.commit();
                //把事务提交,结束,最后把conn返回给连接池
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return isTransfer;
    }

}

dao层:

 1 package com.study.transfer.dao;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 import org.apache.commons.dbutils.QueryRunner;
 7 
 8 import com.study.util.C3P0Utils;
 9 
10 public class TransferDao {
11 
12     public int  inMoney(Connection conn, String inName, double money) throws SQLException {
13         //Connection conn=C3P0Utils.getConnection();
14         QueryRunner qr=new QueryRunner();
15         String sql="update account set money=money+? where name=?";
16         int number=qr.update(conn, sql, inName,money);
17         return number;
18     }
19 
20     public int outMoney(Connection conn, String outName, double money) throws SQLException {
21 //        Connection conn=C3P0Utils.getConnection();
22         QueryRunner qr=new QueryRunner();
23         String sql="update account set money=money-? where name=?";
24         int number =qr.update(conn, sql, outName,money);
25         return number;
26     }       
 }

 DBUtils 事务提交对上面的代码进行了修改:

service层:

public class TransferService {
 
    public boolean transfermoney(String inName, String outName, double money) {
        //调用dao层的inMoney 和  outMoney 
        
        TransferDao dao=new TransferDao();
        Connection conn=null;
        boolean isTransfer=true;
        int number1=-1;
        int number2=-1;
        try {
            //开启事务
            C3P0Utils.startTransaction();
            number1=dao.inMoney(inName ,money);
            number2=dao.outMoney(outName,money);
            if (number1==-1 || number2==-1) {
                //当sql语句的任何一条没有执行成功,就回滚的初始状态
                conn.rollback();
            }
        } catch (Exception e) {
            isTransfer=false;
            try {
                C3P0Utils.rollbackTransaction();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally{
            try {
                C3P0Utils.commitTransaction();
                //把事务提交,结束,最后把conn返回给连接池
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return isTransfer;
    }

dao层:

public class TransferDao {

    public int  inMoney( String inName, double money) throws SQLException {
        Connection conn=MyC3P0Utils.getCurrenConnection();
        QueryRunner qr=new QueryRunner();
        String sql="update account set money=money+? where name=?";
        int number=qr.update(conn, sql, money,inName);
        return number;
    }

    public int outMoney( String outName, double money) throws SQLException {
        Connection conn=MyC3P0Utils.getCurrenConnection();
        QueryRunner qr=new QueryRunner();
        String sql="update account set money=money-? where name=?";
        int number =qr.update(conn, sql, money,outName);
        return number;
    } 

}

C3P0Utils 的代码改变:

public class C3P0Utils {
    private static    ComboPooledDataSource dataSource=new ComboPooledDataSource("login");
    private static ThreadLocal<Connection > tl=new ThreadLocal<Connection>();
    // ThreadLocal 只能存储一个变量
    //可TreadLocal<List<Object>>          
    //获取当前线程的连接connection 
    public  static Connection getCurrenConnection(){
        Connection conn = tl.get();
        if (conn==null) {
            conn=getConnection();
            tl.set(conn);
        }    
        return conn;
    }
    //开启事务
    public static void startTransaction() throws SQLException{
        Connection conn=getCurrenConnection();
        conn.setAutoCommit(false);    
    }
    //回滚事务
    public static void rollbackTransaction() throws SQLException{
        getCurrenConnection().rollback();
    }
    //提交事务
    public static void commitTransaction() throws SQLException{
        Connection conn=getCurrenConnection();
        conn.commit();
        //将Connection从ThreadLocal移除
        tl.remove();
        conn.close();
        
    }
    public static DataSource getDataSource(){
        return dataSource;
    }
    
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

 

posted @ 2017-11-07 20:24  逆水行舟!  阅读(1219)  评论(0编辑  收藏  举报