java 多线程中,一个线程中出现异常,所有线程都回滚,实例
时间: 2023-12-29 08:26:10 浏览: 89
在 Java 多线程中,如果一个线程出现异常,需要让所有线程都回滚的话,可以使用以下的实例代码:
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class MultiThreadRollbackDemo {
private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb?useSSL=false";
private static final String USER = "root";
private static final String PASSWORD = "password";
private static final ThreadLocal<Connection> connectionHolder = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
// 创建 3 个线程
Thread t1 = new Thread(new Worker());
Thread t2 = new Thread(new Worker());
Thread t3 = new Thread(new Worker());
// 启动线程
t1.start();
t2.start();
t3.start();
// 等待所有线程完成
t1.join();
t2.join();
t3.join();
System.out.println("All workers finished successfully.");
}
static class Worker implements Runnable {
@Override
public void run() {
Connection conn = getConnection();
connectionHolder.set(conn);
try {
// 开始事务
conn.setAutoCommit(false);
// 执行一些操作
// ...
// 模拟异常
if (Thread.currentThread().getName().equals("Thread-1")) {
throw new RuntimeException("Something went wrong.");
}
// 提交事务
conn.commit();
} catch (Exception e) {
// 出现异常,回滚事务并抛出异常
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
throw new RuntimeException(e);
} finally {
// 关闭连接
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
// 移除线程变量
connectionHolder.remove();
}
}
private Connection getConnection() {
try {
Connection conn = connectionHolder.get();
if (conn == null) {
conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
connectionHolder.set(conn);
}
return conn;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
```
在这个示例中,我们创建了三个线程,并且在每个线程中都执行了一些操作。如果某个线程抛出异常,其他线程也会回滚事务。我们使用了 ThreadLocal 来存储每个线程的连接对象,保证了线程安全。在 run() 方法中,我们使用 try-catch-finally 块来处理事务回滚和连接关闭的逻辑。如果出现异常,我们会回滚事务并抛出运行时异常,以便在主线程中检查到异常。最后,我们在主线程中等待所有线程完成后打印一条成功的消息。
阅读全文