一、概念
事务(Transaction)是指一组操作的集合,这些操作要么全部成功,要么全部失败。事务的四大特性(ACID)确保了数据的完整性和一致性:
-
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部回滚。
-
一致性(Consistency):事务完成后,数据库的状态必须是合法的。
-
隔离性(Isolation):多个事务同时执行时,事务之间不会互相干扰。
-
持久性(Durability):事务提交后,所做的更改将永久保存。
@Transactional 注解解读 : @Transactional
是 Spring 中声明式事务管理的核心注解,用于标识某个方法或类需要事务支持。
-
作用范围:
-
可以标注在类上:表示该类的所有公共方法都受事务管理。
-
可以标注在方法上:仅对特定方法启用事务。
-
-
常用参数:
-
propagation
:定义事务的传播行为(见下文详细介绍)。 -
isolation
:设置事务的隔离级别,决定事务之间如何相互隔离。 -
rollbackFor
:指定哪些异常会触发事务回滚,默认回滚运行时异常。 -
readOnly
:标志事务是否只读,优化查询性能。
-
注意:
Spring 默认在运行时异常(如 RuntimeException
)或错误时回滚事务,但不会回滚编译时异常(如 IOException
)。如果需要回滚编译时异常,可以在 @Transactional
注解中通过 rollbackFor
参数显式指定。例如:@Transactional(rollbackFor = Exception.class)
。
事务的传播行为: 传播行为定义了当前事务方法在被调用时与外部事务的关系。
-
REQUIRED
:默认传播行为,如果当前有事务则加入该事务,如果当前没有事务,则创建新事务。传播行为定义了事务方法在调用时的执行方式,例如是否加入现有事务,是否创建新事务等。REQUIRED
是最常见的传播行为,适用于需要与外部事务共享同一个事务上下文的场景。 -
REQUIRES_NEW
:每次都会创建新事务。这种传播行为适用于需要完全独立于外部事务的操作场景。例如,当需要确保某段逻辑无论外部事务的状态如何都必须执行时,可以使用REQUIRES_NEW
来强制开启新事务。 -
NESTED
:嵌套事务,依赖外部事务。嵌套事务允许一个事务包含多个子事务。如果嵌套的事务回滚,外部事务可以选择继续执行,也可以回滚整个事务。
二、代码示例
Controller层:
java
@RestController
public class EmpController {
@Autowired
private EmpService empService;
@PostMapping
public Result add(@RequestBody Emp emp) {
log.info("新增员工: {}", emp);
empService.add(emp);
return Result.success();
}
}
Mapper层:
java
@Service
public class EmpService {
@Autowired
private EmpMapper empMapper;
@Autowired
private EmpExprMapper empExprMapper;
@Transactional
public void add(Emp emp) {
// 设置创建和更新时间
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
// 新增员工信息
empMapper.add(emp);
// 新增员工的工作经历
List<EmpExpr> exprList = emp.getExprList();
if (!CollectionUtils.isEmpty(exprList)) {
exprList.forEach(empExpr -> {
empExpr.setEmpId(emp.getId());
});
empExprMapper.addBatch(exprList);
}
}
}
代码解析:
-
@Transactional
:-
标注在
add
方法上,表示该方法中的所有数据库操作将作为一个事务处理。 -
如果方法内出现异常,所有操作都会回滚,确保数据一致性。
-
-
回滚机制:
- 如果在新增经历时出现异常(例如
empExprMapper.addBatch
抛出异常),整个事务都会回滚,之前插入的员工信息也会撤销
- 如果在新增经历时出现异常(例如
三、总结
-
事务的声明方式:
-
使用
@Transactional
注解简化事务管理。 -
注解可以加在方法上或类上,类上注解适用于所有方法,但一般推荐加载Service层的特定方法上。
-
-
事务的回滚:
-
Spring 默认在运行时异常(如
RuntimeException
)或错误时回滚事务。 -
如果需要回滚检查型异常,可以在
@Transactional
注解中设置rollbackFor
属性。
-