简体   繁体   English

sqlite 不更新表/数据库繁忙 [锁定] 使用 java

[英]sqlite not updating tables / database busy [locked] using java

I am using java and sqlite for an application.When I try to update a table works fine , but when I am trying to update a second one table directly after the first one , sqlite tells me is busy[locked].I searched for solution but couldn't find.I am closing all Resultsets , PreparedStatements and Connection of the first update before starting the second one but it doesn't work.Any practical solution or any cause of this error?我正在为应用程序使用 java 和 sqlite。当我尝试更新表时工作正常,但是当我尝试在第一个表之后直接更新第二个表时,sqlite 告诉我正忙 [锁定]。我搜索了解决方案但找不到。在开始第二个更新之前,我正在关闭第一个更新的所有 Resultsets 、 PreparedStatements 和 Connection ,但它不起作用。任何实际的解决方案或导致此错误的任何原因?

    String sql2 = "UPDATE wages SET EPIDOMAADEIAS = ?,FMYEPIDOMATOSADEIAS = ?,ERGODOTHSEPIDOMAADEIAS = ?,ERGAZOMENOSEPIDOMAADEIAS = ? WHERE SURNAME = ?";


                if(kathgoria.equals("ΥΠΑΛΛΗΛΟΣ")){
                    model.addRow(new String[]{surname,etairia,kathgoria,ep,erg,ergod,fmyS,syn});
                     ps = connection.prepareStatement(sql2);
                     try {
                        ps.setString(1,epS);
                        ps.setString(2, fmySS);
                        ps.setString(3, ergodS);
                        ps.setString(4, ergS);
                        ps.setString(5, surname);
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    int reS1 = 0;
                    try {
                        reS1 = ps.executeUpdate();
                        ps.close();
                        connection.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }   
                }

I had this problem and any solutions readed (close connections, close resultsets, etc) did not works for me.我遇到了这个问题,并且读取的任何解决方案(关闭连接、关闭结果集等)对我都不起作用。 The only font that really helped for me was follow a transaction schema as follows:唯一真正对我有帮助的字体是遵循如下的交易模式:

  1. Create the connection创建连接

    private Connection connect() {
        // SQLite connection string
        String url = "jdbc:sqlite:C://sqlite/db/test.db";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }

  1. Declare: n String sentences you need, 1 Resultset, 1 connection and n Prepared statemens as you would like to do in your transation.声明:您需要的 n 个字符串句子、1 个结果集、1 个连接和 n 个准备好的语句,就像您在交易中想要做的那样。 Example:例子:
    // SQL for creating a new material
    String sqlMaterial = "INSERT INTO materials(description) VALUES(?)";
            
    // SQL for posting inventory
    String sqlInventory = "INSERT INTO inventory(warehouse_id,material_id,qty)"
                    + "VALUES(?,?,?)";

    ResultSet rs = null;
    Connection conn = null;
    PreparedStatement pstmt1 = null, pstmt2 = null;

(*) You can use a list as well (pstmt[]) if you have more than to sentences for your transaction. (*) 如果您的交易有多个句子,您也可以使用列表 (pstmt[])。

  1. Open a try/catch/finally block and implment your transaction as follows:打开一个 try/catch/finally 块并按如下方式实现您的交易:
        try {
            // connect to the database
            conn = this.connect();
            if(conn == null)
                return;
            
            // set auto-commit mode to false
            conn.setAutoCommit(false);
            
            // 1. insert a new material
            pstmt1 = conn.prepareStatement(sqlMaterial,
                    Statement.RETURN_GENERATED_KEYS);

            pstmt1.setString(1, material);
            int rowAffected = pstmt1.executeUpdate();

            // get the material id
            rs = pstmt1.getGeneratedKeys();
            int materialId = 0;
            if (rs.next()) {
                materialId = rs.getInt(1);
            }

            if (rowAffected != 1) {
                conn.rollback();
            }
            // 2. insert the inventory
            pstmt2 = conn.prepareStatement(sqlInventory);
            pstmt2.setInt(1, warehouseId);
            pstmt2.setInt(2, materialId);
            pstmt2.setDouble(3, qty);
            // 
            pstmt2.executeUpdate();
            // commit work
            conn.commit();

        } catch (SQLException e1) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException e2) {
                System.out.println(e2.getMessage());
            }
            System.out.println(e1.getMessage());
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt1 != null) {
                    pstmt1.close();
                }
                if (pstmt2 != null) {
                    pstmt2.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e3) {
                System.out.println(e3.getMessage());
            }
        }

Example extracted from - https://www.sqlitetutorial.net/sqlite-java/transaction/ .示例摘自 - https://www.sqlitetutorial.net/sqlite-java/transaction/

Note that also this example helps to understand how you are be able to rollback transaction if anything doesn't works without generates inconsistencies in database.请注意,此示例还有助于了解如果任何事情都不起作用而不会在数据库中产生不一致,您如何能够回滚事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM