【Spring学习06】基于xml和注解的事务声明控制

1. 基于xml的事务声明控制

1.1 什么是事务声明控制

Spring 的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中声明用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务

作用:

  1. 事务管理不侵入开发的组件。具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可
  2. 在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便

注意:Spring 声明式事务控制底层就是AOP。

接下来,我们使用转账的例子进行说明。

1.2 为什么要声明式事务控制

基础环境准备:在dao层实现往账户入账和出账的方法,在service实现转账方法,在controller调用转账方法进行模拟转账功能。
dao层:

public class AccountDaoImpl implements AccountDao {

    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
    }

    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    }
}

service层:

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        //int i = 1/0;
        accountDao.in(inMan,money);
    }
}

controller层:

public class AccountController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = app.getBean(AccountService.class);
        accountService.transfer("Adrian","Young",500);
    }
}

在数据库中创建account表。
在这里插入图片描述
接下来我们运行程序,实现转账。看表中数据变化:
在这里插入图片描述
可以看出,转账成功实现。
但是,如果转账时候出现异常,会出现什么结果呢,这里我们设置一个自杀式异常
在这里插入图片描述
运行程序,看数据库中表的变化
在这里插入图片描述
可以看出,出账成功,入账失败,500块钱凭空消失了。因此我们需要使用事务进行控制转账流程,避免上述情况出现。

1.3 声明式事务控制的实现

  1. 配置平台事务管理器
<!--配置平台事务管理器  因为事务的增强那一块需要平台事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
  1. 配置通知 即事务的增强
 <!--通知  事务的增强  tx:事务控制的命名空间-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--设置事务的属性信息的-->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="save" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="findAll" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
            <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
            <!--            哪些方法需要被增强  *代表任意-->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
  1. 配置事务的aop织入
<!--配置事务的aop织入-->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.ex1.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>

接下来,我们运行上次同样的程序
在这里插入图片描述
在这里插入图片描述
可以看出,程序出现报错,但是,数据库中的数据并没有改变,说明事务成功帮助我们解决了数据丢失问题。
接下来,我们把自杀式错误关闭,运行程序:
在这里插入图片描述
在这里插入图片描述
可以看出,转账进行成功。

总结
在这里插入图片描述

2. 基于注解的事务声明控制

2.1 使用注解的事务声明控制

首先,使用注解需进行包扫描,这时,首先的引入context命名空间下的包扫描

<context:component-scan base-package=“com.ex1”></context:component-scan>

对accountDao和accountService使用注解进行注入

@Repository(“accountDao”)
@Service(“accountService”)

同时,对accountDao类和accountService类下的成员变量使用@Autowired进行注入
在这里插入图片描述
对需要事务控制的切点(方法)使用@Transactional进行注入
在这里插入图片描述
当然,也可以在该方法的类上使用@Transactional进行注入,这种方法则表明对该类下的所有方法都进行 事务控制。

接下来,配置平台事务管理器

<!--配置平台事务管理器  因为事务的增强那一块需要平台事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

最后,配置事务注解驱动

<tx:annotation-driven transaction-manager="transactionManager"/>

以上,就是使用注解来控制事务声明的方法步骤。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值