Spring事物管理

一.事物的概念?

事物可以看做是由对数据库的若干操作组成的一个单元

事物是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,提供将事物中对数据库的所有已完成的操作全部撤销,滚回到事物开始的状态,避免出现由于数据不一致而导致接下来的一系列错误.

事物的出现是为了确保数据的完整性和一致性,确保用户的每一个操作都是可靠的,事物中的每一步操作都必须执行,只要有发生异常就回退到事物未开始的操作状态,这些事物要么都执行,要么都取消,从而保证数据满足原子性,一致性.在目前的企业开发中,事物的管理是必不可少的.

二.事物的四大特性

事物具有四大特性: 原子性,一致性,隔离性,持久性

  • 原子性(Atomicity): 事物是一个原子操作,由于一系列的动作组成.事物的原子性确保动作要么全部完成,要么完全不起作用

  • 一致性(Consistency): 事物在完成时,必须是所有的数据都保持一致

  • 隔离性(Isolation): 并发事物执行之间无影响.在一个事物内部的操作对其他事物是不产生影响的,这需要事物隔离级别来指定隔离性

  • 持久性(Durability): 一旦事物完成,数据库的改变必须是持久化的

三.Spring事物管理

Spring事物管理分为两种形式: 编程式事物和声明式事物

在进行事物管理之前我们首先要进行配置,Spring针对不同的dao框架,提供了不同的实现类.Jdbc,mybatis 事物管理实现类是 DataSourceTransactionManager.

配置事物管理器:

<!-- 配置 spring 事务管理类, 并注入数据源 -->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
 </bean>

编程式事物:

编程式事物管理在代码中很少使用,这种方式需要注入一个事务管理对象TransactionTemplate ,然后在我们代码中需要提交事务或回滚事务时自己写代码实现.此处我们不再进一步了解.

声明式事物:

声明式事务管理建立在AOP的基础上,其本质是对方法前后进行拦截,所以声明式事物管理是方法级别的.

Spring声明式事物管理有两种方式:

基于xml文件实现和基于注解方式实现,此处我们使用以基于注解方式实现

1.首先我们要开启注解事务管理:

<!-- 开启注解事务管理 -->
 <tx:annotation-driven transaction-manager="transactionManager"/>

2.在 service 中控制事务:

 @Service
 @Transactional
 public class AdminService {
 ​
 }

这样我们就开启了Spring事物管理,下面我们举一个简单的栗子更为深刻的理解事务管理:

我们在这里设计一个简单的转账业务进行示例

实现原理:

我们以之前创建的数据库中admin表的password作为用户的金额,设置两个方法模拟一个账户中金额增加功能,一个账户中金额减少功能.在我们开启事物管理功能后,这两个事物就应该满足事物的原子性,要么同时执行了数据库操作,要么都没有执行.我们首先调用sub()方法模拟一个账户中金额减少,在调用add()方法模拟另一个账户增加相应的金额.以运行期异常模拟实际操作过程中可能出现的异常情况,这样Spring事物管理就会识别到这个异常,为了确保安全及保证原子性,就不会向数据库提交事物,并且将已执行代码进行回滚.回到调用之前的状态.

如果我们开启事务管理,并且它有效的执行,那么当我们的sub()方法中出现了运行期异常,或者sub()方法调用之后,add()方法未调用之前出现了运行期异常,那么Spring事务管理就不会向数据库提交事物,即数据库中两个账户的金额都保持不变.这样就体现出了Spring的事务管理功能.

要是没有开启事务管理或者事务管理功能失效,那么当我们执行完sub()方法后就会向数据库提交事物,即使在add()方法未执行之前出现了异常情况,由于已经提交了事务,此账户中的金额还是会减少;而add()方法无法正常执行,因此账户中的金额没有增加,这样就出现了问题.

代码实现:

1.在AdminDao中编写两个方法add()和sub()模拟增加金额和减少金额事务

package com.ffyc.springdemo.dao;
 ​
 ​
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Repository;
 ​
 @Repository
 public class AdminDao {
 ​
     @Autowired
     JdbcTemplate jdbcTemplate;
 ​
     public void add(){
         jdbcTemplate.update("update admin set password = password +300 where id = 2");
     }
 ​
     public void sub(){
         jdbcTemplate.update("update admin set password = password -300 where id = 3");
     }
 }

2.在AdminService中开启事物管理,并调用增加,减少金额的方法.

package com.ffyc.springdemo.service;
 ​
 import com.ffyc.springdemo.dao.AdminDao;
 import com.ffyc.springdemo.model.Admin;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 ​
 @Service
 @Transactional
 public class AdminService {
 ​
     @Autowired
     AdminDao adminDao;
 ​
     public void zhuanZhang(){
         adminDao.sub();
         System.out.println(10/0); //此处模拟出现一个运行期异常
         adminDao.add();
     }
     
 }
 ​

3.在测试类中调用:

 package com.ffyc.springdemo.test;
 ​
 import com.ffyc.springdemo.service.AdminService;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 ​
 public class Test1 {
 ​
     @Test
     public  void test() {
 ​
         ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
         AdminService adminService = app.getBean("adminService", AdminService.class);
         adminService.zhuanZhang();
     }
 }
 ​

4.运行结果分析:

 

由于sub()方法之后出现了运行时异常,Spring事务管理功能就不会向数据库提交事务,因此此时两个账户中金额应该均保持不变,经核实亦是如此,说明Spring事务管理功能正常运行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写代码的菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值