AdSense

網頁

2021/1/12

Spring Boot Data JPA PlatformTransactionManager 手動管理交易

Spring Boot Data JPA使用PlatformTransactionManager在程式中手動管理交易。

範例環境:

  • Spring Boot 2.3.2
  • Spring Data JPA

Spring進行資料庫交易時,除了在方法前加上@Transactional來管理交易外,也可使用PlatformTransactionManager在程式中手動管理交易。

下面DepartmentService.deleteDepartment(long id)依傳入的部門ID來刪除部門資料及所屬員工資料,資料異動操作共兩次。這邊用PlatformTransactionManager以程式的方式手動管理交易。

執行交易前呼叫PlatformTransactionManager.getTransaction(TransactionDefinition definition)取得目前的交易或新建一個交易狀態物件TransactionStatus,然後做為PlatformTransactionManager提交(commit)或回滾(rollback)的參數。

DepartmentService

package com.abc.demo.service;

import com.abc.demo.entity.Employee;
import com.abc.demo.repository.DepartmentRepository;
import com.abc.demo.repository.EmployeeRepository;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.sql.SQLException;
import java.util.List;

@Log4j2
@Service
public class DepartmentService {

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    public void deleteDepartment(long id) {

        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            List<Employee> employeeList = employeeRepository.findByDepartmentId(id);
            employeeRepository.deleteInBatch(employeeList); // 刪除部門所屬員工資料
            departmentRepository.deleteById(id); // 刪除部門資料
            if (id == 1L) {
                throw new SQLException("Database transaction error!!"); // 模擬交易發生錯誤
            }
            platformTransactionManager.commit(transactionStatus); // 提交
        } catch (Exception e) {
            log.error(e.getMessage());
            platformTransactionManager.rollback(transactionStatus); // 回滾
        }
    }
}

參考github


沒有留言:

AdSense