day47-JDBC和連接池03

JDBC和連接池038.事務8.1事務介紹

  • 基本介紹
  1. JDBC程序中當一個Connection對象創建時,默認情況下是自動提交事務:每次執行一個SQL語句時,如果執行成功,就會向數據庫自動提交,而不能回滾 。
  2. JDBC程序中為了讓多個SQL語句作為一個整體執行,需要使用事務
  3. 調用Connection的setAutoCommit(false)可以取消自動提交事務
  4. 在所有的SQL語句都執行成功后,調用Connection的commit();方法提交事務
  5. 在其中某個操作失敗或者出現異常時 , 調用Connection的rollback();方法回滾事務
【day47-JDBC和連接池03】
day47-JDBC和連接池03

文章插圖

day47-JDBC和連接池03

文章插圖
8.2事務處理
應用實例
模擬經典的轉賬業務
首先創建一張account表,插入兩條數據
CREATE TABLE ACCOUNT( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) NOT NULL DEFAULT '', balance DOUBLE NOT NULL DEFAULT 0)CHARACTER SET utf8;INSERT INTO ACCOUNT VALUES(NULL,'馬云',3000),(NULL,'馬化騰',10000);SELECT * FROM ACCOUNT;
day47-JDBC和連接池03

文章插圖
package li.jdbc.transaction_;import li.jdbc.utils.JDBCUtils;import org.junit.Test;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;/** * 演示JDBC中如何使用事務 */public class Transaction_ {//沒有使用事務@Testpublic void noTransaction() {//操作轉賬業務//1.得到連接Connection connection = null;//2.組織sql語句String sql = "update account set balance=baLance-100 where id=1";String sql2 = "update account set balance=baLance+100 where id=2";//3.創建PreparedStatement對象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();//在默認情況下 , connection默認自動提交preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); //執行第一條sqlint i = 1 / 0;//拋出異常--模擬異??赡?-可以看到出現異常狀態之后的語句沒有執行preparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate();//執行第二條sql} catch (SQLException e) {e.printStackTrace();} finally {//關閉資源JDBCUtils.close(null, preparedStatement, connection);}}//使用事務來解決@Testpublic void useTransaction() {//操作轉賬業務//1.得到連接Connection connection = null;//2.組織sql語句String sql = "update account set balance=baLance-100 where id=1";String sql2 = "update account set balance=baLance+100 where id=2";//3.創建PreparedStatement對象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();//在默認情況下,connection默認自動提交//將connection設置為不自動提交connection.setAutoCommit(false);preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); //執行第一條sqlint i = 1 / 0;//拋出異常preparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate();//執行第二條sql//在這里提交事務connection.commit();} catch (Exception e) {//如果在try里面出現了異常,就會進入catch語句 , // 這意味著我們可以在catch語句里面進行回滾,即撤銷執行的SQL語句System.out.println("執行發生了異常 , 撤銷已執行的SQL");try {connection.rollback();//沒有填寫保存點就默認回滾到事務開始的狀態} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {//關閉資源JDBCUtils.close(null, preparedStatement, connection);}}}
  1. 沒有使用事務(noTransaction)的運行結果:可以看到因為默認為直接提交事務,在出現異常后沒有執行異常后面的語句就進入了catch語句,造成數據錯誤

day47-JDBC和連接池03

文章插圖
day47-JDBC和連接池03

文章插圖
  1. 使用了事務(useTransaction)之后:可以看到由于在catch語句中進行了回滾操作,在捕獲到異常之后直接進行回滾,保證數據的一致性

day47-JDBC和連接池03

文章插圖
day47-JDBC和連接池03

文章插圖
9.批處理
  • 基本介紹
  1. 當需要成批插入或者更新記錄時,可以采用Java的批量更新機制,這一機制允許多條語句一次性提交給數據庫批量處理 。通常情況下比單獨提交處理更有效率
  2. JDBC的批量處理語句包括下面方法: