【问题标题】:Cannot get exclusive lock on oracle table from jdbc无法从 jdbc 获取 oracle 表的排他锁
【发布时间】:2015-06-02 07:05:11
【问题描述】:

我正在用jsp编写一个简单的代码来从表中删除一些数据。

当我运行这个语句时,

lock table tbl_Booking, tbl_Ticket in exclusive mode

在 oracle 控制台中,它工作正常。

现在当我在 java 代码中使用它时,我无法获得锁。

代码如下:

String req = request.getParameter("T_NO");
    if (con != null){
        String sql = "lock table tbl_Booking, tbl_Ticket in exclusive mode";
        String sql1 = "DELETE FROM tbl_Ticket WHERE T_NO=?";
        String sql2 = "DELETE FROM tbl_Booking WHERE T_NO IN ?";
        Statement stmt = con.createStatement();
        PreparedStatement ps1 = con.prepareStatement(sql1);
        PreparedStatement ps2 = con.prepareStatement(sql2);
        ps1.setString(1, req);
        ps2.setString(1, req);
        if (stmt.execute(sql)){
            if ((ps1.executeUpdate() == 1)&&(ps2.executeUpdate() == 1)){
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Your ticket has been cancelled!");
            }
            else{
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Couldn't Cancel your ticket!");
            }
        }
        else{
            response.setContentType("text");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write("Couldn't get lock!");
        }
    }

每次我得到,

无法锁定!

作为输出。

固定代码:

<%@page import="java.sql.Statement"%>
<%@page contentType="java" pageEncoding="UTF-8"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@include file="oracle_connection.jsp"%>

<%    String req = request.getParameter("T_NO");
    if (con != null) {
        try {
            String sql = "lock table tbl_Booking, tbl_Ticket in exclusive mode";
            String sql1 = "DELETE FROM tbl_Ticket WHERE TICKET_NO=?";
            String sql2 = "DELETE FROM tbl_Booking WHERE TICKET_NO=?";
            Statement stmt = con.createStatement();
            PreparedStatement ps1 = con.prepareStatement(sql1);
            PreparedStatement ps2 = con.prepareStatement(sql2);
            ps1.setString(1, req);
            ps2.setString(1, req);
            stmt.execute(sql);
            if (ps1.executeUpdate() == 1) {
                ps2.executeUpdate();
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Your ticket has been cancelled!");
            } else {
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Couldn't Cancel your ticket!");
            }

        } catch (Exception e) {
            response.setContentType("text");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(e.toString());
        }
    }
%>

【问题讨论】:

  • @FMC 的答案是正确的——如果没有返回结果集,stmt.execute 将返回 false。但是,为什么您会想要在两个不同的表上获得排他锁,只是为了根据似乎是键的内容删除少数行?除非您的目标是构建一个在多个用户尝试使用它时会迅速陷入困境的系统,否则这是没有意义的。我与 Oracle 合作多年,从未遇到过我想手动获取表锁的情况。
  • 我是根据指令来实现锁的。这不是一个完整的东西,只是为了学习目的。也有人告诉我们,我们在这里所做的事情是不切实际的,在现实生活中没有任何意义。

标签: java oracle jsp jdbc


【解决方案1】:

尝试将其包装在 try-catch 块中。

仅仅因为它返回 false 并不意味着它失败了。

try
    {
        stmt.execute(sql);
            if ((ps1.executeUpdate() == 1)&&(ps2.executeUpdate() == 1)){
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Your ticket has been cancelled!");
            }
            else{
                response.setContentType("text");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("Couldn't Cancel your ticket!");
            }
    }
    catch (Exception e)
    {
        response.setContentType("text");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(e.getMessage());
    }

【讨论】:

  • 没错。 execute-s 文档说:“返回:true 如果第一个结果是 ResultSet 对象;false 如果是更新计数或没有结果”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2019-05-01
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多