Spring 申明式事务&事务的传播行为

版权声明:博客知识产权来源命运的信徒,切勿侵权 https://blog.csdn.net/qq_37591637/article/details/85209308

之前的博客讲述了,为什么要有事务?https://blog.csdn.net/qq_37591637/article/details/85207922

现在呢?就在原有的基础上怎么添加事务,使得整个过程只要有一个地方出问题就失败,整个过程的成功才叫成功!

换句话说,如果书的库存够,账户余额不够的话,这个过程就失败,数据库里面的库存和余额都不会减少!


1.在xml文件中配置

红笔标注的颜色都是不可以更改的!固定的模板

<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- 使得事务注解生效 -->
<tx:annotation-driven transaction-manager="transactionManager" />


在原来的方法上面只要申明    @Transactional就可以了

package cn.com.day04;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService{
	@Autowired
	private BookShopDaoImpl bookShopDaoImpl;
	@Transactional
	public void purchase(String username, String isbn) {
		//1.根据书的编号来查询价格
		int price=bookShopDaoImpl.findBookPriceByIsbn(isbn);
		//2.更新书的库存
		bookShopDaoImpl.updateBookStock(isbn);
		//2.根据用户名查询余额,扣除书的价格
		bookShopDaoImpl.updateUserAccount(username, price);
	}

}

 可是新的问题又来了,如果一个客户去买两本书,或者是更多的书籍呢?

如果一本是是80元,一本书是30元,可是账户余额里面只有100元的话,还能买成么》

这个就涉及到了事务的传播行为......


代码如下

一个接口类(根据用户名,书的编号的集合来模拟实现买书的时候库存和账户余额的变化)

package cn.com.day04;
import java.util.List;
public interface BookShopList {
public void purchare(String name,List<String> isbns);
}

实现类

package cn.com.day04;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("bookShopList")
public class BookShopListImpl implements BookShopList {
	@Autowired
	private BookShopService BookShopServiceImpl;
	@Transactional
	public void purchare(String name, List<String> isbns) {
		//一个事务里面包含多个同样运行流程的事务,是继续使用之前的事务还是创建一个新的事务
		for (String isbn : isbns) {
			BookShopServiceImpl.purchase(name, isbn);
		}

	}

}

测试类

package cn.com.day04;

import java.util.Arrays;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFact {
	private static ApplicationContext ioc = null;
	private static BookShopDaoImpl bookShopDaoImpl = null;
	private static BookShopService bookShopServiceImpl=null;
	private static BookShopList bookShop=null;
	static {
		ioc = new ClassPathXmlApplicationContext("bean-jdbc.xml");
	/*	bookShopDaoImpl = ioc.getBean(BookShopDaoImpl.class);
		bookShopServiceImpl=ioc.getBean(BookShopService.class);*/
		bookShop=ioc.getBean(BookShopList.class);
	}

	public void test1() {
		System.out.println(bookShopDaoImpl.findBookPriceByIsbn("1002"));
	}

	public void test2() {
		bookShopDaoImpl.updateBookStock("1001");
	}


	public void test3() {
		bookShopDaoImpl.updateUserAccount("杨枫述", 28);
	}
	public void test4(){
		bookShopServiceImpl.purchase("杨枫述", "1003");
	}
	@Test
	public void test5(){
		bookShop.purchare("杨枫述", Arrays.asList("1002","1001"));
	}
}

默认的情况下,@Transactional(propagation=Propagation.REQUIRES)

条件:

账户余额:100元

第一本书:40元;

第二本书:70元;

结果就是,结果就是,库存都不会变化,余额是100;


默认的情况下,@Transactional(propagation=Propagation.REQUIRES)

条件:

账户余额:100元

第一本书:70元;

第二本书:40元;

结果就是,结果就是,库存都不会变化,余额是100;


如果给设置    @Transactional(propagation=Propagation.REQUIRES_NEW)

条件:

账户余额:100元

第一本书:40元;

第二本书:70元;

结果就是,第一本书的库存减少1,余额是60;


如果给设置    @Transactional(propagation=Propagation.REQUIRES_NEW)

条件:

账户余额:100元

第一本书:70元;

第二本书:40元;

结果就是,库存都不会变化,余额是100;


@Transactional(propagation=Propagation.REQUIRES_NEW)的好处就是

当你执行第一个小的事务的时候,如果成功了,执行第二个,如果第二个失败了,就会返回到第二个的最开始的地方;


 

但是如果你执行第一个小的事务都失败了,就直接回滚到事务最开始的时候

猜你喜欢

转载自blog.csdn.net/qq_37591637/article/details/85209308