场景模拟
参考基于注解的声明式事务
修改Spring的配置文件
将Spring配置文件中去掉tx:annotation-driven标签,并添加配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启组件扫描-->
<context:component-scan base-package="com.yogurt.spring6.xmltx"></context:component-scan>
<!-- 数据源对象 引入外部属性文件,创建数据源对象-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="druidDataSource"></property>
</bean>
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"></property>
</bean>
<!-- 配置事务增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="update" read-only="false" propagation="REQUIRED"></tx:method>
<tx:method name="buy*" read-only="false" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 配置切入点和通知使用的方法-->
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.yogurt.spring6.xmltx.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
</aop:config>
</beans>
Controller
@Controller
public class BookController {
@Autowired
private BookService bookService;
/**
* 买书的方法
* @param bookId
* @param userId
*/
public void buyBook(Integer bookId,Integer userId){
//调用Service方法
bookService.buyBook(bookId,userId);
}
}
Service
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
/**
* 买书的方法
* @param bookId
* @param userId
*/
@Override
public void buyBook(Integer bookId, Integer userId) {
//根据图书id查询图书价格
Integer price = bookDao.getBookPriceByBookId(bookId);
//更新图书库存量 -1
bookDao.updateStock(bookId);
//更新用户表用户余额 -图书价格
bookDao.updateUserBalance(userId,price);
}
}
Dao
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 根据id查询图书价格
* @param bookId
* @return
*/
@Override
public Integer getBookPriceByBookId(Integer bookId) {
String sql = "select price from t_book where book_id = ?";
Integer price = jdbcTemplate.queryForObject(sql, Integer.class, bookId);
return price;
}
/**
* 更新库存信息
* @param bookId
*/
@Override
public void updateStock(Integer bookId) {
String sql = "update t_book set stock = stock -1 where book_id = ?";
jdbcTemplate.update(sql,bookId);
}
/**
* 更新用户表用户余额 -图书价格
* @param userId
* @param price
*/
@Override
public void updateUserBalance(Integer userId, Integer price) {
String sql = "update t_user set balance = balance - ? where user_id = ?";
jdbcTemplate.update(sql,price,userId);
}
}
测试:
@SpringJUnitConfig(locations = "classpath:beans-xml.xml")
public class TestBookTx {
@Autowired
private BookController bookController;
@Test
public void testBuyBook(){
bookController.buyBook(1,1);
}
}