什么是事务?
数据库事务是指一系列严密操作,要么全部成功,要么全部失败。它有四种特性:原子性、一致性、隔离性和持久性。
而spring事务是封装在数据库事务之上的一种事务处理机制,它有两种管理方式:编程式事务和声明式事务。在平时使用中,我们大多使用@Transactional声明式事务来管理,这也是spring推荐的方式,下面例子也统一采用此种方式。
下面我们主要来看看spring事务的传播机制
spring事务的传播机制
spring事务的传播机制有七种:REQUIRED、REQUIRES_NEW、NESTED、SUPPORTS、NOT_SUPPORTED、MANDATORY和NEVER。
首先要知道事务的传播指的是一个方法调用另外一个方法并将事务传递给它,而传播机制是针对被调用者,控制它是否被传播或者被怎样传播。注:后面多次提到 此方法在/不在事务中,指的是调用者是否开启了事务。
下面我们来仔细分析一下这几种传播方式。
REQUIRED(有事务则加入,没有则创建)
REQUIRED是spring事务的默认方式,如果当前方法不在事务中,就创建一个新的事务;如果当前方法在事务中,就加入到这个事务中。
举个例子,我们操作book书籍表和title章节表,先插入book表,然后再插入title表(下面几种传播方式都以这两张表为例)。BookServiceImpl中方法(调用者)调用TitleServiceImpl中方法(被调用者)。下面分两种情况:
1、调用者有事务
@Slf4j
@Service
@AllArgsConstructor
public class BookServiceImpl implements BookService {
private final BookMapper bookMapper;
private final TitleService titleService;
@Override
@Transactional
public void bookTransaction() {
String transactionName = TransactionSynchronizationManager.getCurrentTransactionName();
log.info("调用者中事务:{}", transactionName);
bookMapper.insert(new Book().setAuthor("zpg"));
//传播事务
titleService.titleTransaction();
}
}
@Slf4j
@Service
@AllArgsConstructor
public class TitleServiceImpl implements TitleService {
private final TitleMapper titleMapper;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void titleTransaction() {
String transactionName = TransactionSynchronizationManager.getCurrentTransactionName();
log.info("被调用者中事务:{}", transactionName);
titleMapper.insert(new Title().setName("第一章"));
}
}
// 输出,被调用者使用的是调用者的事务
调用者中事务:com.example.demo.transaction.service.impl.BookServiceImpl.requiredTest
被调用者中事务:com.example.demo.transaction.service.impl.BookServiceImpl.requiredTest
2、调用者无事务
//BookServiceImpl类
@Override
public void bookTransaction() {
String transactionName = TransactionSynchronizat