栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【SpringMVC】编程式事务控制,基于 XML 的声明式事务控制,基于注解的声明式事务控制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【SpringMVC】编程式事务控制,基于 XML 的声明式事务控制,基于注解的声明式事务控制

文章目录
  • 编程式事务控制相关对象
    • PlatformTransactionManager
    • TransactionDefinition
      • 事务隔离级别
      • 事务传播行为
    • TransactionStatus
    • 知识小结
  • 基于 XML 的声明式事务控制
    • 什么是声明式事务控制
      • 声明式事务处理的作用
    • 声明式事务控制的实现
    • 知识要点
  • 基于注解的声明式事务控制
    • 注解配置声明式事务控制解析
    • 知识要点

编程式事务控制相关对象 PlatformTransactionManager

PlatformTransactionManager 接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法。

方法说明
TransactionStatus getTransaction(TransactionDefination defination)获取事务的状态信息
void commit(TransactionStatus status)提交事务
void rollback(TransactionStatus status)回滚事务

注意:
PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,例如:Dao 层技术是jdbc
或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager
Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager

TransactionDefinition

TransactionDefinition 是事务的定义信息对象,里面有如下方法:

方法说明
int getIsolationLevel()获得事务的隔离级别
int getPropogationBehavior()获得事务的传播行为
int getTimeout()获得超时时间
boolean isReadOnly()是否只读
事务隔离级别

设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。

  • ISOLATION_DEFAULT (默认)
  • ISOLATION_READ_UNCOMMITTED (读未提交)
  • ISOLATION_READ_COMMITTED (读提交)
  • ISOLATION_REPEATABLE_READ (可重复读)
  • ISOLATION_SERIALIZABLE (序列化)

想了解的更详细可点击查看:事物的隔离级别

事务传播行为
  • REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)

    例如:A调用B时,B会检查A是否有事务,如果没有就新建一个事务,如果有就加入A的事务。

  • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)

  • MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常

  • REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。

  • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

  • NEVER:以非事务方式运行,如果当前存在事务,抛出异常

  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作

  • 超时时间:默认值是-1,没有超时限制。如果有,以秒为单位进行设置

  • 是否只读:建议查询时设置为只读

TransactionStatus

TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。

方法说明
boolean hasSavepoint()是否存储回滚点
boolean isCompleted()事务是否完成
boolean isNewTransaction()是否是新事务
boolean isRollbackOnly()事务是否回滚
知识小结

编程式事务控制三大对象

  • PlatformTransactionManager:事务管理器
  • TransactionDefinition:事务的定义信息对象(可理解为配置事务的一些属性)
  • TransactionStatus:事务具体的运行状态
基于 XML 的声明式事务控制 什么是声明式事务控制

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

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

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

声明式事务控制的实现

声明式事务控制明确事项:

  • 谁是切点?
  • 谁是通知?
  • 配置切面?

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("tom","lucy",500);
    }
}

applicationContext.xml配置文件




    
    

    
    
        
        
        
        
    

    
    
        
    

    
    
        
    

    
    
    
        
    

    
    
    
        
    

    
    
    
        
        
            
            
            
            
            
            
            
        
        
    

    
    
    
        
    

其中,< tx:method > 代表切点方法的事务参数的配置,例如:
read-only=“false”/>

  • name:切点方法名称
  • isolation:事务的隔离级别
  • propogation:事务的传播行为
  • timeout:超时时间
  • read-only:是否只读

数据库中的数据

controller层运行后数据库结果

结果没有变化,因为代码运行到 int i = 1/0 时抛出了异常,事务进行了回滚,所以数据库的数据都没有变化

当把配置文件中 通知事务的增强 的代码注释掉后再执行的结果

从结果中可以看出,tom少了500,但lucy并没有增加500,原因是tom减完500以后程序抛出了异常,终止了运行,此时还没有执行到lucy增加500的代码

知识要点

声明式事务控制的配置要点

  • 平台事务管理器配置



    

  • 事务通知的配置

    
    
        
        
            
            
            
            
            
            
            
        
        
    
  • 事务aop织入的配置


    

基于注解的声明式事务控制

编写 AccoutDao

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private 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);
    }
}

编写 AccoutService

@Service("accountService")
//可以在类上配置此注解,表示类中的所有方法都进行事务控制
 @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.MANDATORY)
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
	//在方法上配置此注解,表示该方法进行事务控制
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.MANDATORY)
    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
        //int i = 1/0;//让代码抛出异常
        accountDao.in(inMan,money);
    }
}

编写 applicationContext.xml 配置文件




    
    

    
    

    
    
        
        
        
        
    

    
    
        
    

    
    
        
    

    
    

代码不抛出异常时的执行结果:

在不抛出异常的执行结果的基础上,让代码抛出异常时的执行结果:

结果没有变化,因为程序抛出异常后,事务进行了回滚

注解配置声明式事务控制解析

① 使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离
级别、传播行为等。
② 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。
③ 使用在方法上,不同的方法可以采用不同的事务参数配置。
④ Xml配置文件中要开启事务的注解驱动< tx:annotation-driven />

知识要点
  • 注解声明式事务控制的配置要点

    • 平台事务管理器配置(xml方式)
    
        
            
        
    
    • 事务通知的配置(@Transactional注解配置)
    • 使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。

    • 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。

    • 使用在方法上,不同的方法可以采用不同的事务参数配置。

    • Xml配置文件中要开启事务的注解驱动< tx:annotation-driven />

    • 事务注解驱动的配置 < tx:annotation-driven />
    
        
    
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/970546.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号