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

①事务传播属性可以在@Transactional注解的propagation属性中定义。
②有事务的业务逻辑,容器中保存的是这个业务逻辑的代理对象
@Service
public class BookService {
@Autowired
BookDao bookDao;
//结账事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void checkup(String username,String isbn ){
//减少书本的库存
bookDao.updateStock(isbn);
int price = bookDao.getPrice(isbn);
//减少用户账户余额
bookDao.updateAccount(username, price);
}
//修改书籍的价格事务
@Transactional(propagation = Propagation.REQUIRED)
public void updatePrice(String isbn,int price ){
//修改书籍价格
bookDao.updatePrice(isbn,price);
}
}
@Service
public class MulService {
@Autowired
BookService bookService;
@Transactional
public void mulTx(){
//传播行为来设置这个事务方法是不是和之前的大事务共享一个事务(使用同一条连接);
//REQUIRES_NEW
bookService.checkup("Tom", "ISBN-001");//结账事务
//REQUIRED
bookService.updatePrice("ISBN-002", 998);//修改书籍的价格事务
int a = 10/0;
}
}
public class BookTest {
@Test
public void testIDE(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("tx.xml");
MulService bean = ioc.getBean(MulService.class);
bean.mulTx();
}
}
REQUIRED:将之前事务用的connection传递给这个方法使用;
REQUIRES_NEW:这个方法直接使用新的connection;
在该测试中出现数学异常,和大事务同一个Connection连接的小事务(修改书籍的价格事务)不提交,而使用新Connection连接的小事务(结账事务)成功提交。

对于复杂嵌套的事务
multx(){
//REQUIRED
A(){
//REQUIRES_NEW
B(){}
//REQUIRED
c(){}
}
//REQUIRES_NEW
D(){
DDDD()// REQUIRES_NEW不崩,REQUIRED崩
//REQUIRED
E(){
//REQUIRES_NEW
F(){
//10/0,并且异常向外抛(E崩,G崩,D崩,A,C崩)
}
}
//REQUIRES_NEW
G(){}
}
任何处崩,已经执行的REQUIRES_NEW都会成功;
如果是REQUIRED;事务的属性都是继承于大事务的;
而propagation=Propagation.REQUIRES_NEW可以调整
默认:REQUIRED;
REQUIRED:将之前事务用的connection传递给这个方法使用;
REQUIRES_NEW:这个方法直接使用新的connection;
}
// 下面这个是重点
@Test
public void test() throws FileNotFoundException {
BookService bookService = ioc.getBean(BookService.class);
//MulService bean = ioc.getBean(MulService.class);
//bean.mulTx();
//bookService.checkout("Tom", "ISBN-001");
//int price = bookService.getPrice("ISBN-001");
//System.out.println("读取到的数据:"+price);
//System.out.println(bookService.getClass());
//效果都没改(相当于回滚了),虽然mulTx的两个方法都开新车
//bookService.mulTx();
System.out.println(bookService.getClass());
//如果是MulService --mulTx()---调用bookService两个方法
//BookService---mulTx()--直接调用两个方法
/***
* MulServiceProxy.mulTx(){
* bookServiceProxy.checkout();// bookService的代理对象调用方法
* bookServiceProxy.updatePrice();
* }
*
* 本类方法的嵌套调用就只是一个事务;
* BookServiceProxy.mulTx(){
* checkout();// 不是代理对象调方法了,直接调用发发发
* updatePrice();
*
* //以上两句相当于
* bookDao.updateStock(isbn);
* int price = bookDao.getPrice(isbn);
* bookDao.updateBalance(username, price);
*
* bookDao.updatePrice(isbn, price);
* }
*/
}
1738

被折叠的 条评论
为什么被折叠?



