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

Spring声明式事务管理

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

Spring声明式事务管理

一、事务:

       1、 四大特性:【ACID】

                ① 原子性(atomicity):不可分割,表现为一个事务中涉及到的多个操作在逻辑上缺一不可,要求事务中的所有操作要么都执行,要么都不执行

               ②  一致性(consistency):数据一致,所有数据都处于满足业务规则的一致性状态。一个事务不管涉及到多少个操作,都必须保证事务执行前后数据都是正确的;如果有一个或某几个操作失败了,则必须将其他所有的操作撤销,将数据恢复到事务执行前的状态,也就是说回滚

                ③ 隔离性(isolation):要求多个事务在并发执行过程中不会相互干扰

                ④ 持久性(durability):事务执行完成后,对数据的修改永久的保存下来,被写入到持久化存储器中不会因各种系统错误或其他意外情况而受到影响

        2、三种行为:

                ① 开启事务:connection.setAutoCommit(flase)

                ② 提交事务:connection.commit()

                ③ 回滚事务:connection.rollback()

       3、 编程式事务管理:   

                1) 获取数据库连接Connection对象

                2) 取消事务的自动提交

                3) 执行操作

                4) 正常完成操作时手动提交事务

                5) 执行失败时回滚事务

                6) 关闭相关资源

     总结:编程式事务管理不足,将事务管理代码【非业务代码】与业务代码书写一处,导致代码混乱和代码分散问题。

     此时:需要使用AOP思想【先横向提取,再动态织入】,管理事务:声明式事务管理

        4、声明式事务管理:

                1)导入相关jar包

                        spring-aspects-5.3.1.jar

                        com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar  <依赖上jar包>

                2)开启声明式事务管理支持

               3)在需要事务管理的方法或类上,添加@Transactional

        5、不使用事务管理问题

            案例:以买书为例

 
    public void purchase(String userId, String isbn) {
        //1.查询book价格
        Integer price = bookShopDao.getBookPriceByIsbn(isbn);
        //2.修改库存
        bookShopDao.updateBookStock(isbn);
        //3.修改余额
        bookShopDao.updateUserBalance(userId,price);
    }
@Test
    public void testBookShopService(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext_transaction.xml");
        
       BookShopServiceImpl bookShopService = context.getBean("bookShopService", BookShopServiceImpl.class);

        bookShopService.purchase("101","1002");
    }

  purchase() 方法中三个步骤,应该使用事务管理;如果不使用事务管理,可能会出现【修改库存,但未修改余额】问题

     6、使用事务管理 

        1)导入jar包

        
            org.springframework
            spring-aspects
            5.3.1
        

        2)开启声明事务管理支持

    
        
    

    
    

         3)在需要事务管理的方法或类上,添加@Transactional 

    @Transactional
    public void purchase(String userId, String isbn) {
        //1.查询book价格
        Integer price = bookShopDao.getBookPriceByIsbn(isbn);
        //2.修改库存
        bookShopDao.updateBookStock(isbn);
        //3.修改余额
        bookShopDao.updateUserBalance(userId,price);
    }
 @Test
    public void testBookShopService(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext_transaction.xml");

        //事务声明式事务管理【不能使用BookShopServiceImpl接收,原因代码对象与目标对象是兄弟关系】
        
       //BookShopServiceImpl bookShopService = context.getBean("bookShopService", BookShopServiceImpl.class);

        BookShopService bookShopService = context.getBean("bookShopService", BookShopService.class);

        bookShopService.purchase("101","1001");
    }

       7、声明式事务管理中的属性

        1)事务传播行为 :当事务方法被另一个方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务中运行。

                  语法:(propagation = Propagation.REQUIRED)默认

  

        2)事务隔离级别:一个事务与其他事务隔离的程度称为隔离级别

                语法:(isolation = Isolation.REPEATABLE_READ)

           <1>数据库ation=)事务并发问题

            ①脏读:读到了别人更新但未提交的数据

            ②不可重复读:两次读取的值不可重复

            ③幻读:两次读取的表中的记录不一样,好像出现幻觉一样

            <2>隔离级别           MYSQL查询隔离等级语句:show variables like 'tx_isolation'

                ①读未提交:READ  UNCOMMITTED 【1】

                ②读已提交:READ  COMMITTED   【2】

                ③可重复读:REPEATABLE  READ 【4】

                ④串行化:SERIALIZABLE   【8】

           

        

        3) 事务超时 : timeout   可以设置事务在强制回滚之前可以保持多久,防止长期运行的事务占领资源并对整体性能产生影响   

        4)   事务只读:readaonly   可以设置事务只读数据不做修改,帮助数据库引擎优化事务   

        5)  事务异常回滚[不回滚]           

rollbackFor或rollbackForClassName属性:指定遇到时必须进行回滚的异常类型,可以为多个。

noRollbackFor或noRollbackForClassName属性:指定遇到时不回滚的异常类型,可以为多个

二、Spring中的JdbcTemplate框架

1、JdbcTemplate简介

  • JdbcTemplate是持久化层框架【类似:Mybatis】

2 、搭建JdbcTemplate步骤

  • 导入相关jar包

        
            
                org.springframework
                spring-context
                5.3.1
            
            
            
                org.springframework
                spring-jdbc
                5.3.1
            
            
            
                org.springframework
                spring-orm
                5.3.1
            
            
                org.projectlombok
                lombok
                1.18.12
                compile
            
  • 编写核心配置文件

  • 装配JdbcTemplate
        
    
            
        
    
  • 使用JdbcTemplate相应方法

3、 JdbcTemplate常用API

  • update(String sql,Object... params)       增删改通用方

  • batchUpdate(String sql,List params)      批量增删改通用方法

    • queryForObject()
      • queryForObject(String sql,Class clazz,Object... params)

        • 查询单个数值:select count(1) from table

      • queryForObject(String sql,RowMapper mapper,Object... params)

        • 查询单个对象:select col1,col2 ... from table where id=?

  • query(String sql,RowMapper mapper,Object... params)

    • 查询多个对象,通用方法

三、Spring5新特性  

        1、Spring5整合Log4j2

                ①导入jar包


    org.apache.logging.log4j
    log4j-slf4j-impl
    2.11.2
    test

               ②  配置文件





    
    
        
        
            
            
        
    
    
    
    
        
            
        
    

2、spring整合JUnit5

        导入jar包

         Spring5的测试包 :spring-test-5.3.1.jar

        Junit5相关jar包 :apiguardian-api-1.1.0.jar  ;junit-jupiter-api-5.7.0.jar  ;

                   junit-platform-commons-1.7.0.jar  ;    opentest4j-1.2.0.jar


    org.springframework
    spring-test
    5.3.1




    org.junit.jupiter
    junit-jupiter-api
    5.7.2
    test

使用@ExtendWith注解和@ContextConfiguration注解

使用符合注解@SpringJUnitConfig

//@ExtendWith(SpringExtension.class)
//@ContextConfiguration(locations = "classpath:applicationContext_transaction.xml")
@SpringJUnitConfig(locations = "classpath:applicationContext_transaction.xml")
public class TestJunit5 {
    @Autowired
    private BookShopDao bookShopDao;
    @Test
    public void testJunit5(){
        Integer bookPriceByIsbn = bookShopDao.getBookPriceByIsbn("1001");
        System.out.println("bookPriceByIsbn = " + bookPriceByIsbn);
    }
}

          

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/327767.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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