使用 JDBC 驅動程式的事務

使用 JDBC 驅動程式的事務用於控制事務應該提交和回滾的方式和時間。使用 JDBC 驅動程式建立與 MySQL 伺服器的連線

MySQL 的 JDBC 驅動程式可以在這裡下載

讓我們從使用 JDBC 驅動程式獲取與資料庫的連線開始

Class.forName("com.mysql.jdbc.Driver");  
Connection con = DriverManager.getConnection(DB_CONNECTION_URL,DB_USER,USER_PASSWORD);
--->Example for connection url "jdbc:mysql://localhost:3306/testDB");

字符集 :這表示客戶端將用於將 SQL 語句傳送到伺服器的字符集。它還指定伺服器用於將結果傳送回客戶端的字符集。

在建立與伺服器的連線時應該提到這一點。所以連線字串應該是,

jdbc:mysql://localhost:3306/testDB?useUnicode=true&characterEncoding=utf8

有關字符集和排序規則的更多詳細資訊,請參閱此處

當你開啟連線時,AUTOCOMMIT 模式預設設定為 true ,應該更改為 false 以啟動事務。

con.setAutoCommit(false);

你應該在開啟連線後立即呼叫 setAutoCommit() 方法。

否則使用 START TRANSACTIONBEGIN WORK 開始新的事務。通過使用 START TRANSACTIONBEGIN WORK,無需更改 AUTOCOMMIT false 。這將自動禁用。

現在你可以開始事務了。請參閱下面的完整 JDBC 事務示例。

package jdbcTest;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class accTrans {

    public static void doTransfer(double transAmount,int customerIdFrom,int customerIdTo) {

        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
 
        try {
            String DB_CONNECTION_URL = "jdbc:mysql://localhost:3306/testDB?useUnicode=true&characterEncoding=utf8";

            Class.forName("com.mysql.jdbc.Driver");  
            con = DriverManager.getConnection(DB_CONNECTION_URL,DB_USER,USER_PASSWORD);

            --->set auto commit to false
            con.setAutoCommit(false);
            ---> or use con.START TRANSACTION / con.BEGIN WORK

            --->Start SQL Statements for transaction
            --->Checking availability of amount
            double availableAmt    = 0;
            pstmt = con.prepareStatement("SELECT ledgerAmt FROM accTable WHERE customerId=? FOR UPDATE");
            pstmt.setInt(1, customerIdFrom);
            rs = pstmt.executeQuery();
            if(rs.next())
                availableAmt    = rs.getDouble(1);

            if(availableAmt >= transAmount)
            {
                ---> Do Transfer
                ---> taking amount from cutomerIdFrom
                pstmt = con.prepareStatement("UPDATE accTable SET ledgerAmt=ledgerAmt-? WHERE customerId=?");                        
                pstmt.setDouble(1, transAmount);
                pstmt.setInt(2, customerIdFrom);
                pstmt.executeUpdate();

                ---> depositing amount in cutomerIdTo
                pstmt = con.prepareStatement("UPDATE accTable SET ledgerAmt=ledgerAmt+? WHERE customerId=?");                        
                pstmt.setDouble(1, transAmount);
                pstmt.setInt(2, customerIdTo);
                pstmt.executeUpdate();

                con.commit();
            }
            --->If you performed any insert,update or delete operations before 
            ----> this availability check, then include this else part
            /*else { --->Rollback the transaction if availability is less than required
                con.rollback();
            }*/

        } catch (SQLException ex) {
            ---> Rollback the transaction in case of any error
            con.rollback();
        } finally {
            try {
                if(rs != null)  rs.close();
                if(pstmt != null) pstmt.close();
                if(con != null) con.close();
            }
        }
    }
 
    public static void main(String[] args) {
        doTransfer(500, 1020, 1021);
        -->doTransfer(transAmount, customerIdFrom, customerIdTo);
    }
}

JDBC 事務確保事務塊中的所有 SQL 語句都成功執行,如果事務塊中的任何一個 SQL 語句失敗,則中止並回滾事務塊中的所有內容。