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()
và rollback()
.
Bài viết này được đăng tại [free tuts .net]
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
.
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 freetuts.net */ 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;
Bây giờ hãy chạy chương trình trên nhé.
Và kiểm tra dữ liệu lại một lần nữa.
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;
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 đó.