首页 > 代码库 > Spring的事物传播行为

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;@Servicepublic 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已经提交了,

Spring的事物传播行为