Java事务处理-JDBC事务例子

买书的例子 程序应该将图书数量的操作和更新account用户余额的操作作为一个事务来处理,只有这两个操作都完成的情况下,才能提交事务,否则就回滚事务。
 
1  buy.html
    <html>
        <head>
            <title>购买图书</title>
        </head>
        <body>
            购买《Servlet/JSP深入详解》<p>
            <formaction="trade"method="post">
                输入用户名:  <inputtype="text"name="userid"><br>
                输入购买数量:<inputtype="text"name="quantity"><p>
                <inputtype="reset"value="重填">
                <inputtype="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 TradeServletextends HttpServlet
    {
        private Stringurl;
        private String user;
        private String password;
        
        public voidinit()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 在交易的业务逻辑中进行判断 当用户的账户金额小于购买金额的时候 就取消所作的改变
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值