# 事务处理

主要使用Spring@Transactional注解,也称声明式事务管理,是建立在AOP之上其本质是对目标方法进行拦截,在方法开始之前创建或者加入一个事务,在执行完方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需通过基于@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。@Transactional注解的详细使用即事务管理详细说明可自行查阅相关文档。

下面以添加员工信息为例演示声明式事务的使用方式。

1.在模块oa-user-serviceStaffService中创建testNoTransactiontestExistTransaction两个抽象方法,方法1不加事务管理,方法2使用事务管理。

/**
 * 测试发生异常-没有事务管理
 */
void testNoTransaction();

/**
 * 测试发生异常-使用@Transactional管理事务
 */
void testExistTransaction();

2.在模块oa-user-serviceStaffServiceImpl中完成testNoTransactiontestExistTransaction的方法实现,两个方法的逻辑都是各自添加两个员工信息,方法1没有使用@Transactional注解,方法2使用了@Transactional注解,即用Spring来帮助我们管理事务。

/**
 * 测试发生异常-没有事务管理
 */
public void testNoTransaction() {
    Staff staff = new Staff();
    staff.setName("员工姓名1");
    staff.setGender("男");
    staff.setAge(20);
    staff.setEmail("11111111@qq.com");
    staff.setPhone("13111111111");
    staff.setDescription("测试事务添加员工姓名1");
    insert(staff);

    Staff staff2 = new Staff();
    staff2.setName("员工姓名2");
    staff2.setGender("女");
    staff2.setAge(30);
    staff2.setEmail("22222222@qq.com");
    staff2.setPhone("13222222222");
    staff2.setDescription("测试事务添加员工姓名2");
    insert(staff2);

    // 主动抛出异常
    int result = 10/0;
}

/**
 * 测试发生异常-使用@Transactional管理事务
 */
@Transactional
public void testExistTransaction() {
    Staff staff = new Staff();
    staff.setName("员工姓名3");
    staff.setGender("男");
    staff.setAge(30);
    staff.setEmail("33333333@qq.com");
    staff.setPhone("13333333333");
    staff.setDescription("测试事务添加员工姓名3");
    insert(staff);

    Staff staff2 = new Staff();
    staff2.setName("员工姓名4");
    staff2.setGender("女");
    staff2.setAge(40);
    staff2.setEmail("44444444@qq.com");
    staff2.setPhone("13444444444");
    staff2.setDescription("测试事务添加员工姓名4");
    insert(staff2);

    // 主动抛出异常
    int result = 10/0;
}

3.在模块oa-user-controllerStaffController中添加testNoTransactiontestExistTransaction方法。

/**
 * 测试发生异常-没有事务管理
 *
 * @return
 */
@GetMapping("/testNoTransaction")
public BaseResponse testNoTransaction() {
    staffService.testNoTransaction();
    return BaseResponse.success();
}

/**
 * 测试发生异常-使用@Transactional管理事务
 *
 * @return
 */
@GetMapping("/testExistTransaction")
public BaseResponse testExistTransaction() {
    staffService.testExistTransaction();
    return BaseResponse.success();
}

4.我们请求StaffControllertestNoTransaction方法,该方法的作用是测试在没有事务管理情况下添加员工后发生异常的结果,接口的请求方式和响应结果如下

请求方式

url:http://localhost:8367/api/staff/testNoTransaction
method:GET

响应结果

{
    "code":"99001009",
    "msg":"业务处理异常",
    "data":null,
    "success":false
}

观察数据库中员工1和员工2被成功添加,说明没有事务管理情况下,及时发生异常也不会回滚。

transaction_1

5.我们请求StaffControllertestExistTransaction方法,该方法的作用是测试在使用@Transactional注解进行事务管理情况下添加员工后发生异常的结果,接口的请求方式和响应结果如下

请求方式

url:http://localhost:8367/api/staff/testExistTransaction
method:GET

响应结果

{
    "code":"99001009",
    "msg":"业务处理异常",
    "data":null,
    "success":false
}

观察数据库中员工3和员工4没有被添加进来,说明有事务管理情况下,发生异常会进行回滚。

transaction_2