Java使用PrepareStatement实现多SQL语句执行及事务回滚
在实际开发中,我们经常需要执行多条SQL语句,并且要保证这些SQL语句要么全部执行成功,要么全部执行失败。这就需要使用事务来确保数据的一致性。在Java中,可以使用PrepareStatement来执行多个SQL语句并实现事务回滚。
PrepareStatement简介
PrepareStatement是Java中用于执行SQL语句的接口之一,它继承自Statement接口,是Statement的子接口。与Statement接口不同的是,PrepareStatement可以预编译SQL语句,提高SQL语句的执行效率,并且能够防止SQL注入攻击。
多SQL语句执行
在Java中,可以使用PrepareStatement的addBatch()方法和executeBatch()方法来执行多个SQL语句。
try {
Connection conn = DriverManager.getConnection(url, username, password);
conn.setAutoCommit(false); // 关闭自动提交
String sql1 = "INSERT INTO table1 VALUES(1, 'value1')";
String sql2 = "INSERT INTO table1 VALUES(2, 'value2')";
PreparedStatement ps = conn.prepareStatement(sql1);
ps.addBatch();
ps = conn.prepareStatement(sql2);
ps.addBatch();
ps.executeBatch();
conn.commit(); // 提交事务
} catch (SQLException e) {
e.printStackTrace();
}
在上面的代码中,我们先创建了一个Connection对象,然后关闭了自动提交功能,接着分别创建了两个SQL语句并使用PrepareStatement的addBatch()方法将它们添加到批处理中,最后使用executeBatch()方法执行批处理,最终使用commit()方法提交事务。
事务回滚
在执行多个SQL语句时,如果其中一条SQL语句执行失败,我们需要回滚事务,保证数据的一致性。
try {
Connection conn = DriverManager.getConnection(url, username, password);
conn.setAutoCommit(false); // 关闭自动提交
String sql1 = "INSERT INTO table1 VALUES(1, 'value1')";
String sql2 = "INSERT INTO table1 VALUES(2, 'value2')";
String sql3 = "INSERT INTO table1 VALUES('a', 'value3')"; // 故意制造错误
PreparedStatement ps = conn.prepareStatement(sql1);
ps.addBatch();
ps = conn.prepareStatement(sql2);
ps.addBatch();
ps = conn.prepareStatement(sql3);
ps.addBatch();
ps.executeBatch();
conn.commit(); // 提交事务
} catch (SQLException e) {
e.printStackTrace();
conn.rollback(); // 回滚事务
}
在上面的代码中,我们故意让第三条SQL语句执行失败,这时候会捕获SQLException并执行conn.rollback()方法进行事务回滚。
事务处理的原理
事务处理是数据库系统保证数据完整性的一种机制,它依靠ACID四个特性来保证数据的一致性。
- 原子性(Atomicity):事务要么全部执行成功,要么全部执行失败,不会出现部分成功部分失败的情况。
- 一致性(Consistency):事务执行前后数据库的一致性保持不变。
- 隔离性(Isolation):事务之间是相互隔离的,一个事务的执行不会受到其他事务的干扰。
- 持久性(Durability):一旦事务提交,其结果将持久保存在数据库中,即使系统故障也不会丢失。
示例
下面是一个包含多SQL语句执行和事务回滚的完整示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TransactionExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "123456";
try {
Connection conn = DriverManager.getConnection(url, username, password);
conn.setAutoCommit(false); // 关闭自动提交
String sql1 = "INSERT INTO table1 VALUES(1, 'value1')";
String sql2 = "INSERT INTO table1 VALUES(2, 'value2')";
String sql3 = "INSERT INTO table1 VALUES('a', 'value3')"; // 故意制造错误
PreparedStatement ps = conn.prepareStatement