MySQL JDBC事务

时间:2019-11-20 08:52:37  来源:igfitidea点击:

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

设置自动提交模式

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

Connection conn = DriverManager.getConnection(dbURL,dbUser,dbPassword);
conn.setAutoCommit(false);

一旦将自动提交模式设置为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();
}

MySQL JDBC事务示例

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

我们将在一次交易中执行插入候选人和分配技能的工作。
步骤如下:

  • 将一条记录插入候选人表,并获得插入的ID。

  • 将一组候选人ID和技能ID插入候选人参数表中。

  • 如果以上所有操作均成功,则提交事务,否则将其回滚。

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

package org.theitroad;

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 theitroad.local
 */
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"), 
                        "[email protected]", "(408) 898-5641", skills);
    }
}

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

SELECT * FROM candidates
ORDER BY id DESC;

现在,我们运行程序。

并再次检查候选人表:

并还检查候选人技能表以查看是否有作业。

SELECT * FROM candidate_skills;

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