事务隔离级别(isolation)
- 读未提交
- 读已提交
- 可重复读
- 可串行化
数据库和Spring指定隔离级别不同时
若数据库支持Spring事务设置的隔离级别,则以Spring设置的为准;反之,以数据库的隔离级别为准。
事务传播(propagation)
传播类型
OrderService#generateOrder和AccountService#deductStock
REQUIRED
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// generateOrder方法存在事务,deductStock就加入,不存在就新建。
@Transactional(propagation = Propagation.REQUIRED)
public void deductStock() {
System.out.println("扣减库存");
} SUPPORTS
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// generateOrder方法存在事务,deductStock就加入,不存在就以非事务方式执行,即跟随
@Transactional(propagation = Propagation.SUPPORTS)
public void deductStock() {
System.out.println("扣减库存");
} MANDATORY(强制性的)
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// generateOrder方法存在事务,deductStock就加入,不存在则抛异常
@Transactional(propagation = Propagation.MANDATORY)
public void deductStock() {
System.out.println("扣减库存");
} REQUIRES_NEW
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// deductStock方法总是会创建新事务,generateOrder方法存在事务时,则会将其挂起,即
// deductStock方法与generateOrder方法的事务无关,互不干扰。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void deductStock() {
System.out.println("扣减库存");
} NOT_SUPPORTED
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// deductStock方法以非事务方式执行,generateOrder方法存在事务时,则会将其挂起。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void deductStock() {
System.out.println("扣减库存");
} NEVER
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// deductStock方法以非事务方式执行,generateOrder方法存在事务时,则会抛异常。
@Transactional(propagation = Propagation.NEVER)
public void deductStock() {
System.out.println("扣减库存");
} NESTED
@Transactional
public void generateOrder() {
System.out.println("下单");
accountService.deductStock();
}
// generateOrder方法存在事务时,deductStock方法则会开启子事务。若子事务的异常信息被catch了,则父事务不会进行回滚
// generateOrder方法不存在事务时,deductStock方法则会开启新事务
@Transactional(propagation = Propagation.NESTED)
public void deductStock() {
System.out.println("扣减库存");
} 事务失效场景
场景一: 同类中非事务方法调用事务方法
@Service
public class UserService {
@Autowired
private UserDao userDao;
// 非事务方法调用事务方法
public void transfer() {
transfer(1,2);
}
/**
* 事务不会生效
* @param fromId
* @param toId
*/
@Transactional
public void transfer(int fromId, int toId) {
userDao.deductBalance(fromId);
int i = 1 / 0;
userDao.recharge(toId);
}
} 应用场景
存在3个方法,在a方法中调用了b和c方法,实现b事务失败只回滚b中的事务,c事务失败回滚整个事务。
@Service public class AService { @Autowired private BService bService; @Autowired private CService cService; @Transactional public void a() { try { bService.b(); } catch (Exception e) { System.out.println("事务失败"); } cService.c(); } } @Service public class BService { // b事务是a事务的子事务,在a事务中已经将b事务的异常捕获了,所以b事务失败只会回滚自己的事务,不影响整个事务 // 此处不可用REQUIRES_NEW传播方式,因为c事务失败后,在REQUIRES_NEW传播方式下,b事务不会跟着回滚 @Transactional(propagation = Propagation.NESTED) public void b() { // 数据库操作 } } @Service public class CService { @Transactional public void c() { // 数据库操作 } }超时时间(timeout)
设置事务等待的超时时间。

京公网安备 11010502036488号