MySQL JDBC Transaction

在本教程中,您将学习如何使用 Connection 对象的 commit() 和 rollback() 方法来控制事务。

设置自动提交模式

当您连接到 MySQL 数据库时,自动提交模式默认设置为true 。这意味着一旦语句成功执行,更改将应用​​到数据库。如果您想控制何时提交事务,可以调用Connection对象的setAutoCommit()方法,如下所示:

Connection conn = DriverManager.getConnection(dbURL,dbUser,dbPassword);
conn.setAutoCommit(false);Code language: Java (java)

将自动提交模式设置为false后,您可以调用Connection对象的commit()rollback()方法来提交或回滚事务。

请注意,您应该始终在打开数据库连接后立即调用setAutoCommit()方法。

提交和回滚事务

一旦自动提交模式设置为false ,您就可以提交或回滚事务。使用这些方法的流程如下:

try(Connection conn = DriverManager.getConnection(dbURL,dbUser,dbPassword);){
   conn.setAutoCommit(false);
	
   // perform operations such as insert, update, delete here
   // ..
	
   // if everything is OK, commit the transaction
   conn.commit();

} catch(SQLException e) {
   // in case of exception, rollback the transaction
   conn.rollback();
}Code language: Java (java)

MySQL JDBC 事务示例

在此示例中,我们将在candidates表中插入一条新记录,并为新插入的候选人分配一些技能。

mysql jdbc 示例数据库图

我们将在一次事务中执行插入候选人和分配技能。步骤如下:

  1. candidates表中插入一条记录并获取插入的 ID。
  2. 将一组候选人 ID 和技能 ID 插入到candidate_skills表中。
  3. 如果以上操作均成功,则提交事务,否则回滚。

以下是使用 JDBC 事务的完整示例。

package org.mysqltutorial;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 *
 * @author mysqltutorial.org
 */
public class Main {
  /**
   * Insert and assign skills to a specific candidates
   * @param firstName
   * @param lastName
   * @param dob
   * @param email
   * @param phone
   * @param skills 
   */
    public static void addCandidate(String firstName,String lastName,Date dob, 
                                    String email, String phone, int[] skills) {
        
        Connection conn = null;
        
        // for insert a new candidate
        PreparedStatement pstmt = null;
        
        // for assign skills to candidate
        PreparedStatement pstmtAssignment = null;
        
        // for getting candidate id
        ResultSet rs = null;

        try {
            conn = MySQLJDBCUtil.getConnection();
            // set auto commit to false
            conn.setAutoCommit(false);
            // 
            // Insert candidate
            // 
            String sqlInsert = "INSERT INTO candidates(first_name,last_name,dob,phone,email) "
                              + "VALUES(?,?,?,?,?)";
            
            pstmt = conn.prepareStatement(sqlInsert,Statement.RETURN_GENERATED_KEYS);

            pstmt.setString(1, firstName);
            pstmt.setString(2, lastName);
            pstmt.setDate(3, dob);
            pstmt.setString(4, phone);
            pstmt.setString(5, email);

            int rowAffected = pstmt.executeUpdate();
            
             // get candidate id
            rs = pstmt.getGeneratedKeys();
            int candidateId = 0;
            if(rs.next())
                candidateId = rs.getInt(1);
            //    
            // in case the insert operation successes, assign skills to candidate
            //
            if(rowAffected == 1)
            {
                // assign skills to candidates
                String sqlPivot = "INSERT INTO candidate_skills(candidate_id,skill_id) "
                                 + "VALUES(?,?)";
                
                pstmtAssignment = conn.prepareStatement(sqlPivot);
                for(int skillId : skills) {
                    
                    pstmtAssignment.setInt(1, candidateId);
                    pstmtAssignment.setInt(2, skillId);
                    
                    pstmtAssignment.executeUpdate();
                }
                conn.commit();
            } else {
                conn.rollback();
            }
        } catch (SQLException ex) {
            // roll back the transaction
            try{
                if(conn != null)
                    conn.rollback();
            }catch(SQLException e){
                System.out.println(e.getMessage());
            }
            
            
            System.out.println(ex.getMessage());
        } finally {
            try {
                if(rs != null)  rs.close();
                if(pstmt != null) pstmt.close();
                if(pstmtAssignment != null) pstmtAssignment.close();
                if(conn != null) conn.close();
                
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    public static void main(String[] args) {
       // insert and assign skills 
        int[] skills = {1,2,3};
        addCandidate("John", "Doe", Date.valueOf("1990-01-04"), 
                        "john.d@yahoo.com", "(408) 898-5641", skills);
    }
}Code language: Java (java)

在运行程序之前,让我们检查表candidates表。

SELECT * FROM candidates
ORDER BY id DESC;Code language: Java (java)
候选人表

现在,我们运行该程序。

jdbc事务

并再次检查候选人表:

jdbc事务示例

并检查candidate_skills表以查看作业是否存在。

SELECT * FROM candidate_skills;Code language: Java (java)
候选人技能表

正如您所看到的,我们已成功将数据插入同一事务中的候选人和候选人技能表中。

本教程有帮助吗?