JAVA基礎知識之JDBC——JDBC事務處理及批量更新


JDBC事務

JDBC的事務由Connection提供,默認是打開的。

要開啟事務,則要關閉自動提交,

1 conn.setAutoCommit(false);

提交事務使用

1 conn.commit();

回滾事務使用

1 conn.rollback();

可以在某個位置設置一個保存點,回滾時只回滾到這個點,

1 try {
2     Savepoint sp = conn.setSavepoint();
3 ...
4 } catch (SQLException e) {
5     conn.rollback(sp);
6 }

當Connection遇到一個未處理的SQLException異常時,系統會非正常退出,事務還是會自動回滾。但如果程序捕獲了該異常,則需要在異常處理塊中顯示地回滾。

下面演示JDBC事務的基本用法,

 1 package db;
 2 
 3 
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.IOException;
 7 import java.sql.Connection;
 8 import java.sql.DriverManager;
 9 import java.sql.SQLException;
10 import java.sql.Statement;
11 import java.util.Properties;
12 
13 public class TransactionTest {
14     private String driver;
15     private String url;
16     private String user;
17     private String pass;
18     public void initParam(String paramFile) throws FileNotFoundException, IOException, ClassNotFoundException {
19         //用Properties類加載屬性文件
20         Properties prop = new Properties();
21         prop.load(new FileInputStream(paramFile));
22         driver = prop.getProperty("driver");
23         url = prop.getProperty("url");
24         user = prop.getProperty("user");
25         pass = prop.getProperty("pass");
26         Class.forName(driver);
27     }
28     public void insertInTransaction(String[] sqls) throws SQLException{
29         try (Connection conn = DriverManager.getConnection(url, user, pass)) {
30             //關閉自動提交,即開啟事務
31             conn.setAutoCommit(false);
32             try (Statement stmt = conn.createStatement()) {
33                 for (String sql : sqls) {
34                     stmt.executeUpdate(sql);
35                 }
36                 //提交事務
37                 conn.commit();
38             }catch (SQLException e) {
39                 conn.rollback();
40                 System.out.println("Exception:");
41                 System.out.println(e.getMessage());
42             }
43         } 
44     }
45     public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, IOException, SQLException {
46         TransactionTest tt = new TransactionTest();
47         tt.initParam("mysql.ini");
48         String[] sqls = new String[] {
49                 "insert into jdbc_test values (null, 'aaa','111')",
50                 "insert into jdbc_test values (null, 'bbb', '222')",
51                 "insert into jdbc_test values (null, 'ccc', '333')",
52                 //下面這條sql會失敗,因為已經存在主鍵為2的記錄
53                 "insert into jdbc_test values (2, 'ddd','444')"
54         };
55         tt.insertInTransaction(sqls);
56     }
57 }

上面的第53行sql會引發SQLException異常, 因此前面三個insert都會被回滾, 程序執行如下,

1 Exception:
2 Duplicate entry '2' for key 'PRIMARY'

JDBC批量更新

使用批量更新時,多條sql語句將被作為同一批操作被同時收集,同時提交。

使用Statement收集sql的方法為

1 stmt.addBatch(sql1);
2 stmt.addBatch(sql1);
3 stmt.addBatch(sql1);
4 ...

同時執行所有sql的方法為執行Statement的executeBatch().  (JDK.8中如果執行影響記錄太多,則可以用executeLargeBatch()方法)

stmt.executeBatch();

之后可以提交更新,為了達到批量更新的目的,程序應該在批量操作之前關閉自動提交,然后收集sql,當批量操作執行之后,提交事務,並恢復之前的自動提交模式。

關鍵代碼如下,

 1     public void insertInTransaction(String[] sqls) throws SQLException{
 2         try ( Connection conn = DriverManager.getConnection(url, user, pass)) {
 3             //關閉自動提交,即開啟事務
 4             conn.setAutoCommit(false);  5             try(Statement stmt = conn.createStatement()) {
 6                 for (String sql : sqls) {
 7  stmt.addBatch(sql);  8                 }
 9  stmt.executeBatch(); 10                 //提交事務
11  conn.commit(); 12             } catch (SQLException e) {
13  conn.rollback(); 14                 System.out.println("Exception:");
15                 System.out.println(e.getMessage());
16             } finally {
17                 conn.setAutoCommit(true); 18             }
19         } 
20     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM