声明事务
配置文件applicationContext.xml的配置
<!-- 使注解有用 -->
<context:component-scan base-package="top.biglin"/>
<!-- 配置事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务注解 proxy-target-class="true" 这个很重要,没有它会报NoSuchBeanDefinitionException的错误 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
如果没有proxy-target-class="true"可能会报错NoSuchBeanDefinitionException
ServiceImpl的代码,添加注解:@Transactional
/**
* @author Chiawei
* @date 2019/1/15 11:28
*/
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {
@Autowired
private BookShopDao bookShopDao;
//添加事务
@Transactional
@Override
public void purchase(String username, String isbn) {
//获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn);
//更新书的库存
bookShopDao.updateBookStock(isbn);
//更新余额
bookShopDao.updateUserAccount(username, price);
}
}
事务的传播

image.png
创建两个事务,一个事务调用另一个事务,假设事务B调用事务A,调用两次,那么第二次是用原来的那个还是新开一个呢,此时需要在事务A中用@Transactional(propagation = Propagation.REQUIRES_NEW)注解标记,一般用两个值,一个是:Propagation.REQUIRED,另一个是Propagation.REQUIRES_NEW
Propagation.REQUIRED是默认的,表示在多次调用时使用同一个事务A,不另起炉灶
Propagation.REQUIRES_NEW表示每次调用时都另起炉灶,都新开一个事务,事务凉凉之间不干预可以独立运行。
但是如果抛出了异常,那么是会停止中断的
package top.biglin.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;
/**
* @author Chiawei
* @date 2019/1/15 11:28
*/
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {
@Autowired
private BookShopDao bookShopDao;
/**
*添加事务,Propagation.REQUIRED,使用调用原来的事务
* Propagation.REQUIRES_NEW 新开一个事务
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void purchase(String username, String isbn) {
//获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn);
//更新书的库存
bookShopDao.updateBookStock(isbn);
//更新余额
bookShopDao.updateUserAccount(username, price);
}
}
package top.biglin.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author Chiawei
* @date 2019/1/15 14:15
*/
@Service("cashier")
public class CashierImpl implements Cashier {
@Autowired
private BookShopServiceImpl bookShopService;
@Transactional
@Override
public void checkout(String username, List<String> isbns) {
for (String isbn: isbns){
bookShopService.purchase(username, isbn);
}
}
}
/**
* 事务传播
*/
@Test
public void testTransactionPropagation(){
cashier.checkout("AA", Arrays.asList("1001","1002"));
}