Java事务处理-JDBC事务例子

来源:互联网 发布:域名备案进度查询 编辑:程序博客网 时间:2024/05/22 18:22

买书的例子 程序应该将图书数量的操作和更新account用户余额的操作作为一个事务来处理,只有这两个操作都完成的情况下,才能提交事务,否则就回滚事务。

1  buy.html

<html>    <head>        <title>购买图书</title>    </head>    <body>        购买《Servlet/JSP深入详解》<p>        <form action="trade" method="post">            输入用户名:  <input type="text" name="userid"><br>            输入购买数量:<input type="text" name="quantity"><p>            <input type="reset" value="重填">            <input type="submit" value="购买">        </form>    </body></html>

2  TradeServlet.java

package servlet;import javax.servlet.*;import java.io.*;import javax.servlet.http.*;import java.sql.*;public class TradeServlet extends HttpServlet{    private String url;    private String user;    private String password;        public void init() throws ServletException{        ServletContext sc=getServletContext();        String driverClass=sc.getInitParameter("driverClass");        url=sc.getInitParameter("url");        user=sc.getInitParameter("user");        password=sc.getInitParameter("password");        try{            Class.forName(driverClass);        }catch(ClassNotFoundException ce)        {            throw new ServletException("加载数据库驱动失败!");        }    }        public void doGet(HttpServletRequest req, HttpServletResponse resp)               throws ServletException,IOException{        Connection conn=null;        Statement stmt=null;        PreparedStatement pstmt=null;        ResultSet rs=null;                resp.setContentType("text/html;charset=gb2312");        PrintWriter out=resp.getWriter();                req.setCharacterEncoding("gb2312");                String userid=req.getParameter("userid");        String quantity=req.getParameter("quantity");                if(null==userid || userid.equals("") ||            null==quantity || quantity.equals("")){                        out.println("错误的请求参数");            out.close();        }else{            try{                conn=DriverManager.getConnection(url,user,password);                                conn.setAutoCommit(false);                conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);                                stmt=conn.createStatement();                rs=stmt.executeQuery("select price,amount from bookinfo where id=3");                rs.next();                float price=rs.getFloat(1);                int amount=rs.getInt(2);                                int num=Integer.parseInt(quantity);                if(amount>=num){                    pstmt=conn.prepareStatement("update bookinfo set amount = ? where id = 3");                    pstmt.setInt(1,amount-num);                    pstmt.executeUpdate();                }else{                    out.println("您所购买的图书库存数量不足。");                    out.close();                    return;                }                pstmt=conn.prepareStatement("select balance from account where userid = ?");                pstmt.setString(1,userid);                rs=pstmt.executeQuery();                                rs.next();                float balance=rs.getFloat(1);                                float totalPrice=price*num;                                if(balance>=totalPrice){                    pstmt=conn.prepareStatement("update account set balance = ? where userid = ?");                    pstmt.setFloat(1,balance-totalPrice);                    pstmt.setString(2,userid);                    pstmt.executeUpdate();                }else{                    conn.rollback();                    out.println("您的余额不足。");                    out.close();                    return;                }                conn.commit();                out.println("交易成功!");                out.close();            }catch(SQLException se){                if(conn!=null){                    try{                        conn.rollback();                    }catch(SQLException ***){                        ***.printStackTrace();                    }                }                 se.printStackTrace();            }finally{                if(rs!=null){                    try{                        rs.close();                    }catch(SQLException se){                        se.printStackTrace();                    }                    rs=null;                }                if(stmt!=null){                    try{                        stmt.close();                    }catch(SQLException se){                        se.printStackTrace();                    }                    stmt=null;                }                if(pstmt!=null){                    try{                        pstmt.close();                    }catch(SQLException se){                        se.printStackTrace();                    }                    pstmt=null;                }                if(conn!=null){                    try{                        conn.close();                    }catch(SQLException se){                        se.printStackTrace();                    }                    conn=null;                }            }        }    }        public void doPost(HttpServletRequest req, HttpServletResponse resp)               throws ServletException,IOException{        doGet(req,resp);    }}


1  44、45行 调用请求对象的getParameter()方法得到用户名和购买图书的数量
 
2  60行 调用Connection对象的setAutoCommit()方法 传递 false参数 取消自动提交
 
3  61行 调用Connection对象的setTransactionIsolation()方法设置事务的隔离等级为Repeatable Read
 
4  99行 如果用户的余额不足 那么这次交易失败 调用Connection的rollback()方法,回到交易开始之前的状态,也就是回到bookinfo表中书的书目没发生改变的时候
 
注意: 如果在调用rollback()方法之前调用了commit()方法,那么只能回滚到上一次调用commit()方法之后所作的改变
 
5  104行 若果所有的操作都成功了 调用Connection对象的commit()方法提交事务,也就是向数据库提交所有的改变
 
6  在交易过程中,若果发生了异常 那么就在114行 调用Connection对象的rollback()方法回滚所有的改变
 
 
上面这个servlet用到了两种方式保证交易的正常进行
 
1 利用异常处理机制 一旦交易过程发生异常 就取消所有的改变
2 在交易的业务逻辑中进行判断 当用户的账户金额小于购买金额的时候 就取消所作的改变


原文地址:http://blog.chinaunix.net/uid-26284395-id-3037410.html

0 0
原创粉丝点击