Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从JAVA执行操作时,如何最小化数据库表上的死锁?_Java_Sql Server_Web Applications_Database Connection_Connection Pooling - Fatal编程技术网

从JAVA执行操作时,如何最小化数据库表上的死锁?

从JAVA执行操作时,如何最小化数据库表上的死锁?,java,sql-server,web-applications,database-connection,connection-pooling,Java,Sql Server,Web Applications,Database Connection,Connection Pooling,我面临着例外 com.microsoft.sqlserver.jdbc.SQLServerException:事务(进程ID 493)在与另一个进程的锁|通信缓冲区资源上死锁,并被选为死锁受害者。重新运行事务。 当大量用户访问我的站点的特定事务时。这是因为表上有锁,其他人请求获取此特定表上的锁。 另外,20个表用于此特定事务,并且至少有5个表在执行第一个delete查询,然后插入新数据,这可能会长时间保留该表并导致死锁。下面是示例代码 public void save2(){ c

我面临着例外 com.microsoft.sqlserver.jdbc.SQLServerException:事务(进程ID 493)在与另一个进程的锁|通信缓冲区资源上死锁,并被选为死锁受害者。重新运行事务。

当大量用户访问我的站点的特定事务时。这是因为表上有锁,其他人请求获取此特定表上的锁。 另外,20个表用于此特定事务,并且至少有5个表在执行第一个delete查询,然后插入新数据,这可能会长时间保留该表并导致死锁。下面是示例代码

public void save2(){
        con = DBConnFactory.getConnection();
        con.setAutoCommit(false);
        String deleteQuery1 = "delete from TEST_TABLE1";
        String insertQuery1 = "insert into TEST_TABLE1 values ('66','7')";

        String deleteQuery2 = "delete from TEST_TABLE2";
        String insertQuery2 = "insert into TEST_TABLE2 values ('66','7')";

        String deleteQuery3 = "delete from TEST_TABLE3";
        String insertQuery3 = "insert into TEST_TABLE3 values ('66','7')";

        String deleteQuery4 = "delete from TEST_TABLE4";
        String insertQuery4 = "insert into TEST_TABLE4 values ('66','7')";

        ps1 = con.prepareStatement(deleteQuery1);
        ps2 = con.prepareStatement(insertQuery1);
        ps1.executeUpdate();
        ps2.executeUpdate();

        ps1 = con.prepareStatement(deleteQuery2);
        ps2 = con.prepareStatement(insertQuery2);       
        ps1.executeUpdate();
        ps2.executeUpdate();

        ps1 = con.prepareStatement(deleteQuery3);
        ps2 = con.prepareStatement(insertQuery3);
        ps1.executeUpdate();
        ps2.executeUpdate();


        ps1 = con.prepareStatement(deleteQuery4);
        ps2 = con.prepareStatement(insertQuery4);
        ps1.executeUpdate();
        ps2.executeUpdate();

        System.out.println("success2");
        con.commit();
} 公共类数据库连接{

    public static Connection getConnection() {
        Connection conn = null;

        try {

            Context initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:/comp/env");
            DataSource dataSource = (DataSource) envContext.lookup("jdbc/DBConnection");
            if ((conn == null) || conn.isClosed()) {
                conn = dataSource.getConnection();
            }

        } catch (NamingException e) {
            LOG.error("DBConnFactory - JNDI namin error in getConnection =>"+ e.getMessage());
        } catch (SQLException e) {
            LOG.error("DBConnFactory - SQL error in getConnection =>"+ e.getMessage());
        } 

        return conn;
    }
}
我在考虑删除存储过程中的所有表数据,然后根据我的业务逻辑通过JAVA插入。这会有帮助吗?
请建议如何解决此问题,我是否需要更改我的方法?

由于您要删除表中的所有行,请尝试改用
TRUNCATE table TEST\u table 1
。TRUNCATE比Delete快得多,但由于它是DDL语句,因此对其使用有其他限制

String deleteQuery1 = "truncate table TEST_TABLE1;";
您可以使用的另一种方法是将Delete和Insert语句组合到一个批处理中:

String query1 = "delete from TEST_TABLE1; insert into TEST_TABLE1 values ('66','7');";
不带where子句的Delete语句具有完整的表锁,这将阻止执行其他Delete或insert语句。通过将这两个语句组合到一个批处理中,可以减少连接数和 延迟

您可以将所有delete和insert语句组合到一个批处理中

一个值得关注的问题是在不使用where子句的情况下使用Delete。由于您遇到死锁,这意味着您有多个连接同时命中相同的对象。例如,如果在connectionB尝试从表中删除时,connectionA正在插入到Test_表1中,您将面临软冲突的巨大风险ct,其中连接先删除connectionA中的数据,然后再将其用于其他任何操作。在这样的事务系统中,如果没有Where子句,就不应该使用Delete

如果您试图删除要插入的特定值,则应添加Where子句来限制该值。这还可能会将锁定级别从表级别更改为行级别,前提是您有适当的索引,并消除死锁

String query1 = "delete from TEST_TABLE1 where ID = '66'; insert into TEST_TABLE1 values ('66','7');";

请用死锁图更新您的问题。在此之前,无法给您任何答案。实际上,根据我的业务需要,我在delete语句中使用where子句。我使用的是pstmt.addBatch();pstmt.executeBatch();插入数据,因为有多条记录要插入。此外,我对整个事务使用单个连接对象,在某个点失败将回滚整个事务。因为我使用的PreparedStatement正在调用pst.executeUpdate();用于delete和pstmt.executeBatch();对于插入,我是否应该将PreparedStatement对象更改为Statement对象以使查询在单个批处理中执行?如果您不提供所有查询,则很难确定问题。请更新您的问题以更能代表您的问题。此外,代码中的连接对象可能与连接对象不同连接到数据库。如果连接对象是类的一部分,则该类的每个实例都可以有单独的连接。此外,在连接中,可以有多个会话。每个会话可以提交多个批,其中包含多个语句。批通常是发送到数据库进行handli的工作单元ng和死锁发生的位置。当需要与DB交互时,我的web项目中每个类中的每个方法都会调用此静态getConnection方法。DBConnection是一个常见的类,其中定义了静态getConnection,它是从不同类的不同方法调用的。请建议