Spring中事务的传播行为
一、说在前面
1、当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
2、事务的传播行为可以由传播属性指定。Spring 定义了 7 种类传播行为:
(1)REQUIRED:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务里运行。
(2)REQUIRES_NEW:当前的方法必须启动新事务,并在它自己的事务里运行;如果有事务正在运行,应该将它挂起。
(3)MANDATORY:当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常。
(4)NESTED:如果有事务在运行,当前的方法就应该在这个事务的嵌套事务里运行,否则,就启动一个新的事务,并在它自己的事务里运行。
(5)NEVER:当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常。
(6)NOT_SUPPORTED:当前的方法不应该运行在事务中,如果有运行的事务,就将它挂起。
(7)SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则,它可以不运行在事务中。
二、实例代码如下:
本实例是在上一篇文章Spring中声明式事务管理的例子的基础上进行的,重复代码不在赘述,请翻阅上一篇文章。
1、Cashier接口
package com.at.spring.tx;
import java.util.List;
public interface Cashier {
public void checkout(String username,List<String> isbns);
}
2、CashierImpl实现类
package com.at.spring.tx;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("cashier")
public class CashierImpl implements Cashier{
@Autowired
private BookShopService bookShopService;
@Transactional
public void checkout(String username, List<String> isbns) {
for(String isbn:isbns){
bookShopService.purchase(username, isbn);
}
}
}
3、BookShopService接口
package com.at.spring.tx;
public interface BookShopService {
public void purchase(String username,String isbn);
}
4、BookShopServiceImpl实现类
package com.at.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService{
@Autowired
private BookShopDao bookShopDao;
//添加事务注解
/**
* 使用propagation指定事务的传播行为,即当前的事务方法被另外一个事务方法调用时如何使用事务,
* 默认的取值为REQUIRED,即使用被调用方法的事务
* REQUIRES_NEW:使用自己的事务,调用的事务方法的事务被挂起。
*/
@Transactional(propagation=Propagation.REQUIRED)
public void purchase(String username, String isbn) {
//1、获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn);
//2、更新书的库存
bookShopDao.updateBookStock(isbn);
//3、更新用户余额
bookShopDao.updateUserAccount(username, price);
}
}