提交 5890fe98 编写于 作者: 小傅哥's avatar 小傅哥

feat: 注解事务和编程事务

上级 1797ef8a
......@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PluginAutoConfig {
public class PluginAutoConfiguration {
@Bean
public Interceptor plugin() {
......
package cn.bugstack.xfg.dev.tech.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import javax.sql.DataSource;
@Configuration
public class TransactionManagerAutoConfiguration {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehaviorName("PROPAGATION_REQUIRED");
return transactionTemplate;
}
}
......@@ -13,7 +13,7 @@
</resultMap>
<insert id="insert" parameterType="cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeeSalaryPO">
INSERT INTO employee_salary(employee, salary_total_amount, salary_merit_amount, salary_base_amount,
INSERT INTO employee_salary(employee_number, salary_total_amount, salary_merit_amount, salary_base_amount,
create_time, update_time)
VALUES(#{employeeNumber}, #{salaryTotalAmount}, #{salaryMeritAmount}, #{salaryBaseAmount}, now(), now())
</insert>
......
......@@ -2,6 +2,7 @@ package cn.bugstack.xfg.dev.tech.test.domain;
import cn.bugstack.xfg.dev.tech.domain.employee.model.entity.EmployeeInfoEntity;
import cn.bugstack.xfg.dev.tech.domain.employee.service.IEmployeeService;
import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeePO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
......@@ -10,6 +11,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Slf4j
@RunWith(SpringRunner.class)
......@@ -19,6 +21,19 @@ public class IEmployeeServiceTest {
@Resource
private IEmployeeService employeeService;
@Test
public void test_insertEmployInfo() {
EmployeeInfoEntity employeeInfo = new EmployeeInfoEntity();
employeeInfo.setEmployeeNumber("10000022");
employeeInfo.setEmployeeName("小卡拉米");
employeeInfo.setEmployeeLevel("T1");
employeeInfo.setEmployeeTitle("实习工程师");
employeeInfo.setSalaryTotalAmount(new BigDecimal("100"));
employeeInfo.setSalaryMeritAmount(new BigDecimal("10"));
employeeInfo.setSalaryBaseAmount(new BigDecimal("90"));
employeeService.insertEmployInfo(employeeInfo);
}
@Test
public void test_queryEmployInfo() {
EmployeeInfoEntity employeeInfoEntity = employeeService.queryEmployInfo("10000001");
......
......@@ -13,6 +13,8 @@ import java.math.BigDecimal;
@NoArgsConstructor
public class EmployeeInfoEntity {
/** 雇员编号 */
private String employeeNumber;
/** 雇员姓名 */
private String employeeName;
/** 雇员级别 */
......
......@@ -4,6 +4,8 @@ import cn.bugstack.xfg.dev.tech.domain.employee.model.entity.EmployeeInfoEntity;
public interface IEmployeeRepository {
void insertEmployeeInfo(EmployeeInfoEntity employeeInfoEntity);
EmployeeInfoEntity queryEmployInfo(String employNumber);
}
......@@ -12,6 +12,11 @@ public class EmployeeService implements IEmployeeService{
@Resource
private IEmployeeRepository employeeRepository;
@Override
public void insertEmployInfo(EmployeeInfoEntity employeeInfoEntity) {
employeeRepository.insertEmployeeInfo(employeeInfoEntity);
}
@Override
public EmployeeInfoEntity queryEmployInfo(String employNumber) {
return employeeRepository.queryEmployInfo(employNumber);
......
......@@ -4,6 +4,8 @@ import cn.bugstack.xfg.dev.tech.domain.employee.model.entity.EmployeeInfoEntity;
public interface IEmployeeService {
void insertEmployInfo(EmployeeInfoEntity employeeInfoEntity);
EmployeeInfoEntity queryEmployInfo(String employNumber);
}
......@@ -7,7 +7,14 @@ import cn.bugstack.xfg.dev.tech.infrastructure.dao.IEmployeeSalaryAdjustDAO;
import cn.bugstack.xfg.dev.tech.infrastructure.dao.IEmployeeSalaryDAO;
import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeePO;
import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeeSalaryPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
......@@ -19,6 +26,40 @@ public class EmployeeRepository implements IEmployeeRepository {
@Resource
private IEmployeeSalaryDAO employeeSalaryDAO;
@Resource
private TransactionTemplate transactionTemplate;
@Override
public void insertEmployeeInfo(EmployeeInfoEntity employeeInfoEntity) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
EmployeePO employeePO = EmployeePO.builder()
.employeeNumber(employeeInfoEntity.getEmployeeNumber())
.employeeName(employeeInfoEntity.getEmployeeName())
.employeeLevel(employeeInfoEntity.getEmployeeLevel())
.employeeTitle(employeeInfoEntity.getEmployeeTitle())
.build();
employeeDAO.insert(employeePO);
EmployeeSalaryPO employeeSalaryPO = EmployeeSalaryPO.builder()
.employeeNumber(employeeInfoEntity.getEmployeeNumber())
.salaryTotalAmount(employeeInfoEntity.getSalaryTotalAmount())
.salaryMeritAmount(employeeInfoEntity.getSalaryMeritAmount())
.salaryBaseAmount(employeeInfoEntity.getSalaryBaseAmount())
.build();
employeeSalaryDAO.insert(employeeSalaryPO);
} catch (Exception e) {
status.setRollbackOnly();
e.printStackTrace();
}
}
});
}
@Override
public EmployeeInfoEntity queryEmployInfo(String employNumber) {
// 查询雇员
......@@ -27,6 +68,7 @@ public class EmployeeRepository implements IEmployeeRepository {
EmployeeSalaryPO employeeSalaryPO = employeeSalaryDAO.queryEmployeeSalaryByEmployNumber(employNumber);
return EmployeeInfoEntity.builder()
.employeeNumber(employeePO.getEmployeeNumber())
.employeeName(employeePO.getEmployeeName())
.employeeLevel(employeePO.getEmployeeLevel())
.employeeTitle(employeePO.getEmployeeTitle())
......
......@@ -11,6 +11,8 @@ import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeePO;
import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeeSalaryAdjustPO;
import cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeeSalaryPO;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
......@@ -25,8 +27,28 @@ public class SalaryAdjustRepository implements ISalaryAdjustRepository {
@Resource
private IEmployeeSalaryAdjustDAO employeeSalaryAdjustDAO;
/**
* Spring Boot 事务管理的级别可以通过 `@Transactional` 注解的 `isolation` 属性进行配置。常见的事务隔离级别有以下几种:
* 1. `DEFAULT`:使用底层数据库的默认隔离级别。MySQL 默认为 `REPEATABLE READ`,Oracle 默认为 `READ COMMITTED`。
* 2. `READ_UNCOMMITTED`:最低的隔离级别,允许读取未提交的数据变更,可能会导致脏读、不可重复读和幻读问题。
* 3. `READ_COMMITTED`:允许读取已经提交的数据变更,可以避免脏读问题,但可能会出现不可重复读和幻读问题。
* 4. `REPEATABLE_READ`:保证同一事务中多次读取同一数据时,结果始终一致,可以避免脏读和不可重复读问题,但可能会出现幻读问题。
* 5. `SERIALIZABLE`:最高的隔离级别,可以避免脏读、不可重复读和幻读问题,但会影响并发性能。
* <p>
* 在 Spring Boot 中,默认的事务隔离级别为 `DEFAULT`。如果没有特殊需求,建议使用默认隔离级别。
* SpringBoot 事务的传播行为可以通过 `@Transactional` 注解的 `propagation` 属性进行配置。常用的传播行为有以下几种:
* 1. `Propagation.REQUIRED`:默认的传播行为,如果当前存在事务,则加入该事务,否则新建一个事务;
* 2. `Propagation.SUPPORTS`:如果当前存在事务,则加入该事务,否则以非事务的方式执行;
* 3. `Propagation.MANDATORY`:如果当前存在事务,则加入该事务,否则抛出异常;
* 4. `Propagation.REQUIRES_NEW`:无论当前是否存在事务,都会新建一个事务,如果当前存在事务,则将当前事务挂起;
* 5. `Propagation.NOT_SUPPORTED`:以非事务的方式执行操作,如果当前存在事务,则将当前事务挂起;
* 6. `Propagation.NEVER`:以非事务的方式执行操作,如果当前存在事务,则抛出异常;
* 7. `Propagation.NESTED`:如果当前存在事务,则在该事务的嵌套事务中执行,否则新建一个事务。嵌套事务是独立于外部事务的,但是如果外部事务回滚,则嵌套事务也会回滚。
* <p>
* 除了传播行为,`@Transactional` 注解还可以配置其他属性,例如隔离级别、超时时间、只读等。
*/
@Override
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class, timeout = 350, propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public String adjustSalary(AdjustSalaryApplyOrderAggregate adjustSalaryApplyOrderAggregate) {
String employeeNumber = adjustSalaryApplyOrderAggregate.getEmployeeNumber();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册