使用 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 语句失败,则中止并回滚事务块中的所有内容。