Spring的事物传播行为

事物的传播属性:
当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播. 例如: 方法可能继续在现有事务中运行(REQUIRED), 也可能开启一个新事务, 并在自己的事务中运行(Required_NEW).
事务的传播行为可以由传播属性(propagation)指定. Spring 定义了 7 种类传播行为.

这里主要理解一下REQUIRED和REQUIRED_NEW

用例子来说明:
比如一个客户去买两本书,但是账户的余额只能买一本书,那这时应该怎么处理呢?处理方法就是:1要么买一本书,2要么两本一起不买
代码说明:
客户买多本书的接口:

package com.jeremy.springTransaction;
import java.util.List;
public interface cashier {
    void checkOut(String userName,List<String> isbns);
}

实现类:

package com.jeremy.springTransaction;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class cashierImpl implements cashier {
    @Autowired
    BookShopServiceImpl bookShopServiceImpl;
    
    @Transactional
    @Override
    public void checkOut(String userName, List<String> isbns) {
        // TODO Auto-generated method stub
        for (String isbn:isbns) {
            bookShopServiceImpl.purchase(userName, isbn);
        }
    }
}

purchase()方法代码:

@Autowired
    private BookShopDao bookShopDao;

    @Transactional
    @Override
    public void purchase(String username, String isbn) {
        
        //1. 获取书的单价
        int price = bookShopDao.findBookPriceByIsbn(isbn);
        
        //2. 更新数的库存
        bookShopDao.updateBookStock(isbn);
        
        //3. 更新用户余额
        bookShopDao.updateUserAccount(username, price);
    }

完整代码这里下载:

这里只是举例子
当客户需要买两本书时,就需要调用checkout()方法,并启动事务(tx1),但是checkout()方法又需要调用purchase()方法,而这个方法也有事务(tx2),这时tx2是要重新开启一个事务还是放在tx1事务中运行

当放在事务tx1运行时:也就是事务的传播属性(propagation=REQUIRED)时,运行流程如下:
REQUIRED:在现有的事务内运行,一起提交

所以这时客户一本书也买不了,因为事务tx2、tx3都和事务tx1一起提交

当重新开启一个事务时:也就是事务的传播属性(propagation=REQUIRED_NEW)时,运行流程如下:

EQUIRES_NEW. 它表示该方法必须启动一个新事务, 并在自己的事务内运行. 如果有事务在运行, 就应该先挂起它.


所以这时客户能买一本书,因为事务tx2已经提交了,

原文地址:https://www.cnblogs.com/jeremy-blog/p/4057362.html