Xử lý MySQL Transaction bằng Java JDBC Driver

Trong bài viết này mình sẽ hướng dẫn các bạn cách sử dụng phương thức commit() và rollback() trong đối tượng Connection để xử lý Transaction với MySQL.

Thiết lập chế độ Auto Commit

Khi bạn kết nối vào Database MySQL thì mặc nhiên nó sẽ thiết lập chế độ auto-commit là TRUE, điều đó có nghĩa rằng các thay đổi sẽ được áp dụng sau khi câu lệnh thực hiện thành công.

Trong trường hợp bạn muốn kiểm soát kết quả của các câu lệnh thì hãy sử dụng phương thức setAutoCommit () của đối tượng Connection. Cụ thể cú pháp như sau:

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

Khi bạn thiết lập auto-commit là false thì có thể kiểm soát được trạng thái giao dịch (transaction) bằng cách sử dụng hai phương thức commit()rollback().

Bài viết này được đăng tại [kiso.vn]

Lưu ý rằng bạn phải gọi phương thức setAutoCommit nằm phía dưới đoạn code kết nối nhé.

Committing và rolling back transaction

Khi bạn muốn sử dụng transaction trong JDBC MySQL thì bắt buộc phải thiết lập auto-commit là false. Sau đây là đoạn code tổng quát của ví dụ này.

try(Connection conn = DriverManager.getConnection(dbURL,dbUser,dbPassword);){
   conn.setAutoCommit(false);
	
   // Thực hiện các câu lệnh SQL tại đây
   // ..
	
   // Nếu mọi thức OK thì thực hiện commit
   conn.commit();

} catch(SQLException e) {
   // Ngược lai, nếu có lỗi thì hãy rollback
   conn.rollback();
}

Ví dụ về MySQL JDBC transaction

Trong ví dụ này, chúng ta sẽ chèn một bản ghi mới vào bảng candidates, và mỗi ứng viên sẽ có một số kỹ năng nên sẽ có thêm bảng skills và bảng liên kết candidate_skills.

mysql jdbc sample database diagram jpg

Theo như sơ đồ này thì rõ ràng khi muốn thêm kỹ năng cho ứng viên thì bắt buộc phải thêm ứng viên (candidates) thành công trước, sau đó mới có ID ứng viên để thêm ở bảng liên kết (candidate_skills). Các bước thực hiện như sau:

  • Chèn một bản ghi vào bảng ứng cử viên (candidates) và trả về ID đã chèn.
  • Chèn các bản ghi gồm ID ứng viên và ID kỹ năng vào bảng candidate_skills .
  • Nếu tất cả các hoạt động trên thành công thì trạng thái giao dịch là commit, nếu không thì rollback.

Dưới đây là toàn bộ chương trình.

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 kiso.vn
 */
public class Main {
  /**
   * Thêm nhân viên và kỹ năng của nhân viên đó
   * @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;
        
        // Dùng để thêm nhân viên mới
        PreparedStatement pstmt = null;
        
        // Dùng để thêm kỹ năng cho nhân viên
        PreparedStatement pstmtAssignment = null;
        
        // Dùng để lấy ID nhân viên vừa thêm vào
        ResultSet rs = null;

        try {
            conn = MySQLJDBCUtil.getConnection();
            // set auto commit to false
            conn.setAutoCommit(false);
            // 
            // Thêm nhân viên
            // 
            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();
            
             // lấy candidate id
            rs = pstmt.getGeneratedKeys();
            int candidateId = 0;
            if(rs.next())
                candidateId = rs.getInt(1);
            //    
            // Trường hợp thêm nhân viên thành công thì lập tức thêm kỹ năng cho nhân viên đó
            //
            if(rowAffected == 1)
            {
                // Thêm kỹ năng cho nhân viên
                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) {
       // Chương trình chính 
        int[] skills = {1,2,3};
        addCandidate("John", "Doe", Date.valueOf("1990-01-04"), 
                        "john.d@yahoo.com", "(408) 898-5641", skills);
    }
}

Bây giờ hãy kiểm tra xem trong bảng candidates có dữ liệu là gì đã nhé.

SELECT * FROM candidates
ORDER BY id DESC;

candidates table jpg

Bây giờ hãy chạy chương trình trên nhé.

jdbc transaction jpg

Và kiểm tra dữ liệu lại một lần nữa.

jdbc transaction example jpg

Cũng nên kiểm tra xem kỹ năng của nhân viên vừa thêm có ID là 122 tồn tai không nhé.

SELECT * FROM candidate_skills;

candidate skills table jpg

Như vậy là bạn đã thêm thành công một nhân viên mới và kỹ năng cho nhân viên đó.

Bài viết liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *