ORA-00060: Deadlock detected.分析

会话1 

update t1 set a='10’ where id=100;  --执行完,不提交

update t1 set a=‘20’ where id=200  --执行等待会话2的锁。

 

会话2 

update t1 set a='10’ where id=200;  --执行完,不提交

update t1 set a=‘20’ where id=100  --执行等待会话1的锁

 

 

 

直接报错死锁,会话全部回滚。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我们来详细解释一下 ORA-00060deadlock detected while waiting for resource 错误,并用 Java 程序进行举例。 首先,让我们先了解一下什么是死锁。死锁是指两个或多个事务相互等待对方释放资源,导致彼此都无法继续执行的情况。当出现死锁时,Oracle 数据库会选择其中一个事务作为牺牲品来终止,以解除死锁。 在 Java 程序中,死锁通常发生在多个线程同时访问共享资源的情况下。例如,多个线程同时访问同一个数据库表中的数据,如果它们之间没有正确地同步,就可能会产生死锁错误。 下面是一个简单的 Java 程序,用于模拟多线程访问数据库表的情况: ```java import java.sql.*; public class DeadlockExample { public static void main(String[] args) { Connection conn1 = null; Connection conn2 = null; try { // 获取数据库连接 conn1 = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "user1", "password1"); conn2 = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "user2", "password2"); // 创建两个线程,分别执行查询操作和更新操作 Thread t1 = new Thread(new QueryTask(conn1, conn2)); Thread t2 = new Thread(new UpdateTask(conn2, conn1)); // 启动线程 t1.start(); t2.start(); // 等待线程结束 t1.join(); t2.join(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭数据库连接 try { if (conn1 != null) conn1.close(); if (conn2 != null) conn2.close(); } catch (SQLException e) { e.printStackTrace(); } } } } class QueryTask implements Runnable { private Connection conn1; private Connection conn2; public QueryTask(Connection conn1, Connection conn2) { this.conn1 = conn1; this.conn2 = conn2; } public void run() { try { // 在 conn1 上执行查询操作 Statement stmt1 = conn1.createStatement(); ResultSet rs1 = stmt1.executeQuery("SELECT * FROM table1 WHERE column1 = 1"); rs1.next(); System.out.println(rs1.getString("column1")); // 在 conn2 上执行查询操作 Statement stmt2 = conn2.createStatement(); ResultSet rs2 = stmt2.executeQuery("SELECT * FROM table2 WHERE column2 = 2"); rs2.next(); System.out.println(rs2.getString("column2")); // 关闭结果集和语句 rs1.close(); stmt1.close(); rs2.close(); stmt2.close(); } catch (Exception e) { e.printStackTrace(); } } } class UpdateTask implements Runnable { private Connection conn1; private Connection conn2; public UpdateTask(Connection conn1, Connection conn2) { this.conn1 = conn1; this.conn2 = conn2; } public void run() { try { // 在 conn2 上执行更新操作 Statement stmt2 = conn2.createStatement(); stmt2.executeUpdate("UPDATE table2 SET column2 = 3 WHERE column2 = 2"); stmt2.close(); // 在 conn1 上执行更新操作 Statement stmt1 = conn1.createStatement(); stmt1.executeUpdate("UPDATE table1 SET column1 = 2 WHERE column1 = 1"); stmt1.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 在这个例子中,我们创建了两个线程,一个线程执行查询操作,另一个线程执行更新操作。这两个线程分别使用不同的数据库连接(conn1 和 conn2),同时访问两个不同的数据库表(table1 和 table2)。 在 QueryTask 中,我们在 conn1 上执行了一个查询操作,并在 conn2 上执行了另一个查询操作。在 UpdateTask 中,我们在 conn2 上执行了一个更新操作,并在 conn1 上执行了另一个更新操作。 这个程序的运行过程中,可能会导致死锁错误。例如,如果查询操作先获取了 table1 中的行锁,并等待更新操作释放 table2 中的行锁,而更新操作先获取了 table2 中的行锁,并等待查询操作释放 table1 中的行锁,就会产生死锁错误。 当程序出现死锁错误时,Oracle 数据库会选择其中一个事务作为牺牲品来终止,以解除死锁。在 Java 程序中,可以通过捕获 SQLException 异常来处理死锁错误,例如: ```java try { // 执行数据库操作 } catch (SQLException e) { if (e.getErrorCode() == 60) { // 出现死锁错误,进行相应的处理 } else { // 其他类型的 SQLException 错误,进行相应的处理 } } ``` 在捕获 SQLException 异常时,可以通过调用 getErrorCode() 方法来获取错误码,如果错误码为 60,就说明出现了死锁错误。此时,可以进行相应的处理,例如回滚事务、重试操作等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值