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

Spring事务 作者:哇塞大嘴好帅(我爱大嘴网)

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

Spring事务 作者:哇塞大嘴好帅(我爱大嘴网)

Spring事务 作者:哇塞大嘴好帅(我爱大嘴网)
我爱大嘴好帅(我爱大嘴网)
我爱大嘴好帥(我愛大嘴網)
1.事务的特性(ACID)

​ 1.原子性(Atomicity)

​ 2.一致性(Consistency)

​ 3.隔离性(isolation)

​ 4.持久性(Durability)

1.原子性(Atomicity)

​ 比如张三给李四5块钱,然后李四给赵四3块钱。原子性就是这些步骤要不都执行要不都别执行,如果某一步出现问题就回滚撤销。

2.一致性(Consistency)

​ 数据保证在业务上是正确的

3.隔离性(isolation)

​ 两个事务的执行要互不影响,互不干扰,

4.持久性(Durability)

​ 一旦提交事务成功,数据会到数据库持久化保存,也就是拥有保存。

Spring事务管理机制

Spring事务时在数据库事务的基础上进行封装扩展的,主要特性如下

​ 1.支持原有的数据库事务的隔离级别,加入了事务传播的概念

​ 2.提供国歌事务的合并或隔离的功能

​ 3.提供声明式事务,让业务代码与事务分离,事务变得更加易用(AOP)

Spring提供了事务相关的接口

Spring事务管理高层抽象主要包含3个接口,Spring的事务主要通过他们三个共同完成

​ TransactionDefinition

​ 事务定义: 事务定义信息(隔离、传播、只读、超时)

​ PlatformTransactionManager

​ 事务管理器,主要用于平台相关事务的管理、

​ TransactionStatus

​ 获取事务的运行状态

1.1PlatformTransactionManager 事务管理器介绍

参考文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/PlatformTransactionManager.html

commit方法提交事务

getTransaction获取事务状态 里面的TransactionDefinition是事务的定义 ,通过事务的定义信息去获取状态

rollback回滚

Spring为不同的持久层框架提供了不同的PlaformTransactionManaeg的接口实现

事务说明
org.springframework.jdbc.datasource.DataSourceTransactionManager使用Spring JDBC或iBatis进行持久化数据时使用
org.springframework.orm.hibernate5.HibernateTransactionManager使用Hibernate5.0半斤星星持久化数据时使用
org.springframework.orm.jpa.JpaTransactionManager使用JPA进行持久化时使用
org.springframework.jdo.JdoTransactionManager当持久化机制是Jdo时使用
org.springframework.trasanction.jta.JtaTransactionManager使用一个JTA实现来管理事务,在一个事务跨越多个资源必须使用.

DatasourceTransactionManager针对JdbcTemplate、Mybatis事务控制,使用Connection(连接)进行事务管理

开启事务connection.setAutoCommit(false),只有这个为false时候才能进行提交事务connection.commit() 、回滚事务connection.rollback();

1.2 TransactionDefinition 事务定义信息

参考文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/TransactionDefinition.html

**getIsolationLevel ** 获取隔离级别

getName 获取当前事务的昵称

getPropagationBehavior 获取事务传播行为

getTimeout 获取超时时间,默认值是-1.-1就是不超时

isReadonly 判断事务是否只读

常用的事务隔离级别

Isolation Leavelmeaning
DEFAULT使用后端数据库默认的隔离别(Spring中的选择项)
READ_UNCOMMITED允许你读取还未提交的未改变的数据。可能导致脏读、幻读、不可重复读
READ_COMMITTED允许在并发事务已经提交后读取。可防止脏读,但幻读和不重复读依然可以发生
REPEATABLE_READ对相同子弹的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读依然可能发生.
SERIALIZABLE100%服从ACID的隔离级别,确保不发生脏读、幻读、不可重复读。这在所有的隔离级别中是最慢的,他是典型的通过完全锁定在事务张设计的数据表来完成的。

DEFAULT是基于你选择的数据库,来选择你数据库的默认隔离级别

如:Mysql默认隔离级别为REPEATABLE_READ

​ Oracle默认隔离级别 READ_COMMITTED

propagation behavior事务传播行为

7种事务传播级别

事务传播行为类型说明
PROPAGATION_REQUIRED支持当前事务,如果不存在就创建一个
PROPAGATION_SUPPORTS支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY支持当前事务,如果不存在,抛出异常
PROPAGATION_REQUIRES_NEW如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER以非事务方法运行,如果有事务存在,抛出异常
PROPAGATION_NESTED如果当前事务存在,则嵌套事务执行,只针对DataSourceTransactionManager

主要分为三大类:

PROPAGATION_REQUIRED(default) ,PROPAGATION_SUPPORTS ,PROPAGATION_MANDATORY

​ 支持当前事务,A调用B,如果A事务还存在,那么A and B就处于同一个事务,事务默认的传播级别为REQUIRED

PROPAGATION_REQUIRES_NEW,PROPAGATION_NOT_SUPPORTED,PROPAGATION_NEVER

​ 不会支持原来的事务,如A调用B,如果A事务存在,B肯定不会和A处于一个事务。

常用的事务传播行为:REQUIRES_NEW

PROPAGATION_NESTED 不常用

​ 嵌套事务,只对DatasourcetransactionManager有效,底层使用JDBC的SavePoint机制,允许在同一个事务设置保存点,回滚保存点

常用的事务传播行为:NESTED

REQUIRED NESTED REQUIRES_NEW的区分

​ required 只有一个事务(默认,推荐)

​ requires_new 存在两个事务,如果事务存在,挂起事务,重新又开启一个新的事务

​ nested 嵌套事务,事务可以设置保存点,回滚到保存点,选择提交or回滚

2.Spring事务管理 2.1编程式事务

​ 编程式事务就是通过纯代码控制事务,手动提交手动回滚

2.1.1 xml配置

    




    

2.1.2 注解配置
@ComponentScan("com.dazuizui")
public class TransactionConfig{
    
	@Bean
    public TransactionTemple transactionTemplate(DataSourceTransactionManager dataSourceTransactionManager){
        TransactionTemplate transactionTemplate = new TransactionTemplate();
        transactionTemplate.setTransactionManager(transactionTemplate);
        return transactionTemplate;
    }
    
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager dm = new DataSourceTransactionManager();
        dm.setDataSource(dataSource);
        return dm;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDtaSource(dataSource);
        return jdbcTemplate;
    }
    
    @Bean
    public DtaSource dataSource(){
        BasicDataSource ds = new BasicDataSource();
        ds.seturl("url");
        ds.setDriverClassName("com.mysql.jdbc.Driver")
        ds.setUsername("username");
        ds.setPassowrd("password");
        return ds;
    }
}
2.1.3 实现
@Test
public void test1(){
    ApplicationContext ca = new CLassPathXmlApplicationContext("applicationContext.xml");
    UserSerivce userBean = ca.getBean(UserSerivce.class);
    bean.test1();//执行数据库操作
}


public void test2(){
    AnnotationConfigApplicationContext ac= new AnnotationConfigApplicationContext(TransactionConfig.class);
        UserSerivce userBean = ca.getBean(UserSerivce.class);
    bean.test1();//执行数据库操作
}

将调用数据库事务通过Lambda表达式写在transactiontemplate.execute()方法内进行事务事务管理

@Autowired
private TransactionTemplate transactiontemplate		//事务管理器
    
public void test1(){
    transactiontemplate.execute(status - > {
       userMapper.zhuanqian();	//调用数据库小张转钱给小明
        int x = 10086;
        if(x==10086)
            throw new RuntimeException("error");
        userDao.income();	//小明收入小张转的钱
        return null;
    });
}
2.2 申明式事务 2.2.1基于AspectJ xml的配置方式

​ 使用该申明式定要删除配置文件中的事务管理模板中的配置。

​ 也就是这个


    

添加一个事务定义的配置和AOP的配置


    



    
    
    	
        		
           	
            
                
        
    




	
    
    
    

​ 说一下Spring事务的配置:

​ 第一种方法基于XML的配置方法,需要配置事务管理器,然后在配置事务的增强

​ 事务定义主要配置,事务隔离级别、事务传播行为、是否只读、超时时间、发生那些异常不回滚、发生哪些异常滚事务

​ 再通过aop:config设置切面和切入点

2.2.2 注解方法声明式事务
@ComponentScan("com.dazuizui")
@EnableTransactionManagement		//开启注解事务
public class TransactionConfig{    
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager dm = new DataSourceTransactionManager();
        dm.setDataSource(dataSource);
        return dm;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDtaSource(dataSource);
        return jdbcTemplate;
    }
    
    @Bean
    public DtaSource dataSource(){
        BasicDataSource ds = new BasicDataSource();
        ds.seturl("url");
        ds.setDriverClassName("com.mysql.jdbc.Driver")
        ds.setUsername("username");
        ds.setPassowrd("password");
        return ds;
    }
}

如果你想使用事务那么就在Service类的上面加入**@Transactional**就是当前类下所有方法都进行事务管理,如果在方法上使用,那么就这个方法受到事务管理。

​ 说一下Spring事务的配置:

​ 基于注解的,在类上或者方法上添加**@Transactional**

3.Spring 传播特性 3.1 什么是传播特性? What is propagation charecteristics?

​ 当一个事务方法被另一个事务方法调用时(方法A调用方法B),这个事务方法应该如何进行。

​ for example:

@Service
public class test1{
    @Transactional
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }
    @Transactional
    public void function2(){
        System.out.println("function 2 medhod");
    }
}
3.2 Spring的7中传播特性 7 kinds of propagation chanrecteristics of Spring
传播行为(propagation)描述(discribe)
PROPAGATION_REQUIRED默认事务类型,如果没有就新建一个事务;如果有就加入当前事务。
PROPAGATION_SUPPORTS如果没有事务就非事物执行,如果有事务就使用当前事务
PROPAGATION_MANDATORY如果没有事务就抛出异常,如果有就使用当前事务
PROPAGATION_REQUIRES_NEW如果没有事务就非事务执行,所有有就将事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER如果有事务就抛出异常,如果没有就非事务执行
PROPAGATION_NESTED如果没有事务就创建一个事务;如果有就在当前事务种嵌套其他事务
3.2.1详细解说7种传播特性

​ 使用注解设置传播特性例如

​ @Transaction(propagation=Propagation.SUPPORTS)

​ @Transaction(propagation=Propagation.NEVER)

3.2.1.1 PROPAGATION_NEVER

​ 如果function1 或者 function2存在事务那么直接抛出异常

​ for example

@Service
public class test1{
    @Transactional
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }
    @Transactional
    public void function2(){
        System.out.println("function 2 medhod");
    }
}

这样会报错

@Service
public class test1{
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }
    public void function2(){
        System.out.println("function 2 medhod");
    }
}

这样就不会报错

3.2.1.2 PROPAGATION_NOT_SUPPORTED

​ 如果被调用方法发现调用它的方法存在事务那么就将事务挂起(我把你放一边,我做我的事情),

for example

@Service
public class test1{
    @Transactional
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }

    public void function2(){
        System.out.println("function 2 medhod");
    }
}

可以说PROPAGATION_NOT_SUPPORTED and PROPAGATION_NEVER 是死都不要事务

3.2.1.3 PROPAGATION_SUPPORTED

​ 你有事务我就用事务执行,你没有事务我就不按事务执行。

可以说propagation_not_supported是可有可无事务

3.2.1.4 propagation_requires_new

​ 不管有没有事务都必须创建一个事务,如果有事务,就将原来的事务挂起。我创建一个新的

​ for example

@Service
public class test1{
    @Transactional
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }
    @Transactional
    public void function2(){
        System.out.println("function 2 medhod");
    }
}

​ function2不管function1是否存在事务,我function2都必须创建一个事务,当我的事务走完了再去走function1的事务

​ 可以实现子影响父,但父不影响子的效果

3.2.1.5 propagation_nested

​ for example

@Service
public class test1{
    @Transactional
    public void function1(){
        System.out.println("funcion 1 method");
    	function2();
    }
    @Transactional
    public void function2(){
        System.out.println("function 2 medhod");
    }
}

如果function2出现了异常那么function1也跟着回滚

3.2.1.6 propagation_required (默认)

​ 如果没有事务我就创建一个事务,如果有事务那么我就用你的事务

3.2.1.7 propagation_mandatory

​ 如果没有事务我就报错,如果有事务我就用你的

propagation_mandatory 和 propagation_required 和propagation_nested 和 propagation_requires_new 必须有一个事务

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

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

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