Spring--声明式事务基础

声明式事务

概述

编程式事务:

TransactionFilter{

​ try{

​ //获取连接

​ //设置非自动提交

​ chain.doFilter();

​ //提交

​ }catch{

​ //事务回滚

​ }finally{

​ //关闭连接释放资源

​ }

}

或使用AOP环绕通知

​ //获取连接

​ //设置非自动提交

​ 目标代码执行

​ //正常提交

​ //异常回滚

​ //最终关闭

声明式事务:

现在只需要将事务方法利用注解标记出来即可

事务管理代码的固定模式作为一种横切关注点,可以通过AOP方法模块化,进而借助SpringAOP框架实现声明式事务管理

Spring自身提供了该事务切面(事务管理器)

Spring--声明式事务基础

目前使用DataSourceTransactionManager,该事务管理器可以在目标方法运行前后进行事务控制

使用

  1. 环境搭建

dao

@Repository
public class BookDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //1. 修改余额
    public void updateBalance(String username,int price){
        String sql = "UPDATE account SET balance=balance-? WHERE username=?";
        jdbcTemplate.update(sql,price,username);
    }

    //2. 按照图书的ISBN获取某本图书的价格
    public int getPrice(String isbn){
        String sql = "SELECT price FROM book WHERE isbn=?";
        return jdbcTemplate.queryForObject(sql,Integer.class,isbn);
    }

    //3. 修改库存,每次将书本库存减少一
    public void updateStock(String isbn){
        String sql = "UPDATE book_stock SET stock=stock-1 WHERE isbn=?";
        jdbcTemplate.update(sql,isbn);
    }

    //4. 修改图书价格
    public void updatePrice(String isbn,int price){
        String sql = "update book set price=? where isbn=?";

        jdbcTemplate.update(sql,price,isbn);
    }
}

service

@Service
public class BookService {

    @Autowired
    private BookDao bookDao;

    //结账,传入哪个顾客购买了哪本书
    public void checkout(String username,String isbn){
        //1. 修改库存
        bookDao.updateStock(isbn);
        //2. 获取书本价格
        int price = bookDao.getPrice(isbn);

        //3. 修改用户余额
        bookDao.updateBalance(username,price);
    }
}
  1. 快速为某个方法添加事务

1)配置事务管理器

2)开启基于注解的事务

3)给事务方法添加@Transactional注解

<context:component-scan base-package="com.th1024"></context:component-scan>

<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="name" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>

<!--配置JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>

<!--
事务控制
配置事务管理器(切面)让其进行事务控制,导入jar包
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-5.2.6.RELEASE.jar
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--1. 注入数据源-->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--2. 开启基于注解的事务控制模式,依赖tx名称空间-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--3. 给事务方法添加注解@Transactional-->
@Service
public class BookService {

    @Autowired
    private BookDao bookDao;

    //结账,传入哪个顾客购买了哪本书
    @Transactional(propagation = Propagation.REQUIRES_NEW) //添加事务控制注解
    public void checkout(String username,String isbn){
        //1. 修改库存
        bookDao.updateStock(isbn);
        //2. 获取书本价格
        int price = bookDao.getPrice(isbn);

        //模拟网络阻塞
//        int i = 10/0;

        //3. 修改用户余额
        bookDao.updateBalance(username,price);
    }
}

测试

public class TxTest {

    ApplicationContext ioc = new ClassPathXmlApplicationContext("tx.xml");

    @Test
    public void test1(){
        BookService bookService = ioc.getBean(BookService.class);

        bookService.checkout("Tom","ISBN-001");


    }
}
上一篇:事务的传播行为


下一篇:ISBN 号码