Spring事务控制

Spring事务控制

事务定义

  • 访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

  • 事务特性:

    • Atomicity:事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。
    • Consistency:几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致
    • Isolation:事务的执行不受其他事务的干扰
    • Durability:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障
  • 数据库事务实现的原理:

    • 事务的ACID的实现是由关系型数据库 (DBMS)来实现的,DBMS采用日志来实现原子性,一致性与持久性,对于事务的隔离性采用锁机制来实现。
  • 事务隔离等级不同造成的问题:

    • 脏读:读取到其他事务未提交的事务
      • 解决方案:提升隔离级别为Read Committed
      • 原理:使用表级读锁
    • 不可重复读:读取到的一条记录,多次读取到的结果不同
      • 解决方案:提升隔离级别为Repeatable Read 可重复读
      • 原理:使用行级写锁
    • 幻读:在读取过程中数据的条目发生了变化
      • 解决方案:提升隔离级别为Serializable
      • 原理:表级写锁
  • Mysql的InnoDB锁机制(悲观锁)

    • 共享锁/读锁:允许一个事务读取一行,阻止其他事务修改该数据
    • 排他锁/写锁:其他事务不能读与写该数据

Spring事务管理

  • J2EE使用分层设计思想,在业务层对一组逻辑的代码进行事务管理

  • Spring为业务成提供了整套的事务解决方案:

    • PlatformTransactionManager平台事务管理器
    • TransactionDefinition事务定义
    • TransactionStatus事务状态
  • 平台事务管理器的分类

    • DataSourceTransactionManager
      • 适用于Spring JDBC或MyBatis
      • PlatformTransactionManager对象定义了事务的基本操作:
        • 获得事务:TransactionStatus getTransaction(TransactionDefinition definition)
        • 提交事务:void commit(TransactionStatus status)
        • 回滚事务:void rollback(TransactionStatus status)
      • TransactionDefinition事务定义对象
        • 获取事务名称:String getName()
        • 获取事务读写属性:boolean isReadOnly()
        • 获取事务隔离级别:int getIsolationLevel()
        • 获取事务超时时间:int getTimeout()
        • 获取事务传播行为特征:int getPropagationBehavior()
      • TransactionStatus事务状态对象
        • 获取事务是否处于新开启事务状态:boolean isNewTransaction()
        • 获取事务是否处于已完成状态:boolean isCompleted()
        • 获取事务是否处于回滚状态:boolean isRollbackOnly()
        • 刷新事务状态:void flush()
        • 获取事务是否具有回滚存储点:boolean hasSavepoint()
        • 设置事务处于回滚状态:void setRollbackOnly()
    • HibernateTransactionManager
      • 适用于Hibernate3.0及以上版本
  • 使用Spring的AOP实现事务管理

    • 编程式事务:
      • 编写切面程序
     public Object transationMoniter(ProceedingJoinPoint pjp) throws Throwable {
            // 获得事务管理器对象
            PlatformTransactionManager ptm=new DataSourceTransactionManager(dataSource);
            // 获得默认事务定义对象
            TransactionDefinition td=new DefaultTransactionDefinition();
            // 获得事务状态对象
            TransactionStatus transactionStatus = ptm.getTransaction(td);
            // 执行原来方法
            Object proceed = pjp.proceed();
            //提交事务
            ptm.commit(transactionStatus);
            // 返回结果
            return  proceed;
        }
    
    • 配置aop的xml文件
     <aop:config >
            <aop:pointcut id="pt" expression="execution( public * com.itheima.service.impl.AccountServiceImpl.transfer(..))"/>
            <aop:aspect ref="txAdvice">
                <aop:around method="transationMoniter" pointcut-ref="pt"></aop:around>
            </aop:aspect>
        </aop:config>
    
    • 声明式事务:

      • 配置数据库连接池

        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                <property name="driverClassName" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </bean>
        
      • 配置事务管理器(PlatformTransactionManager)

        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"></property>
        </bean>
        
      • 配置事务通知类

         <tx:advice id="txAd" transaction-manager="txManager">
                <tx:attributes>
                    <tx:method name="*" read-only="false" />
                    <tx:method name="get*" read-only="true"/>
                </tx:attributes>
            </tx:advice>
        
      • 配置aop的切入点与切面的方法

         <aop:config>
                <aop:pointcut id="pt" expression="execution(public * com.wx.service..*(..))"/>
                <aop:advisor advice-ref="txAd" pointcut-ref="pt"/>
            </aop:config>
        
    • tx:methord标签属性

      <tx:method
      name="*"				待添加事务的方法名表达式(支持*号通配符),例如get* 、* 、……
      read-only="false"		设置事务的读写属性,true为只读,false为读写
      timeout="-1"			设置事务超时时长,单位秒
      isolation="DEFAULT"		设置事务隔离级别,该隔离级设定是基于Spring的设定,非数据库端
      no-rollback-for=""		设置事务中不回滚的异常,多个异常间使用,分割
      rollback-for=""			设置事务中必回滚的异常,多个异常间使用,分割
      propagation="REQUIRED"	设置事务的传播行为
      />
      
  • 事务传播行为propagation

    • 事务管理员:管理事务的事务

    • 事务协调员:使用者本身需要执行的事务比如crud

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2B2NsTVE-1595069819382)(F:\MarkDownOnte\学习笔记\Spring\assets\1595055067983.png)]

使用注解配置事务

  • 名称:@Transactional

  • 类型:方法注解,类注解,接口注解

    @Transactional(
    readOnly = false,
    timeout = -1,
    isolation = Isolation.DEFAULT,
    rollbackFor = {ArithmeticException.class, IOException.class},
    noRollbackFor = {},
    propagation = Propagation.REQUIRES_NEW
    )
    
  • xml中配置

    <tx:annotation-driven transaction-manager="txManager"/> // 开启注解驱动与指定事务管理器
    
  • 在配置类中开启事务支持

    @EnableTransactionManagement
    

模板对象 spring-jdbc-template

  • spring提供的模板对象

    • TransactionTemplate
    • JdbcTemplate
    • RedisTemplate
    • RabbitTemplate
    • JmsTemplate
    • HibernateTemplate
    • RestTemplate
  • jdbcTemplat

  • redisTemplate整合jeids

    
     @Value("${redis.host}")
        private String hostName;
    
        @Value("${redis.port}")
        private Integer port;
    
    //    @Value("${redis.password}")
    //    private String password;
    
        @Value("${redis.maxActive}")
        private Integer maxActive;
        @Value("${redis.minIdle}")
        private Integer minIdle;
        @Value("${redis.maxIdle}")
        private Integer maxIdle;
        @Value("${redis.maxWait}")
        private Integer maxWait;
    
    @Bean
        //配置RedisTemplate
        public RedisTemplate createRedisTemplate(RedisConnectionFactory redisConnectionFactory){
            //1.创建对象
            RedisTemplate redisTemplate = new RedisTemplate();
            //2.设置连接工厂
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            //3.设置redis生成的key的序列化器,对key编码进行处理
            RedisSerializer stringSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringSerializer);
            redisTemplate.setHashKeySerializer(stringSerializer);
            //4.返回
            return redisTemplate;
        }
     @Bean
        //配置Redis连接工厂
        public RedisConnectionFactory createRedisConnectionFactory(RedisStandaloneConfiguration redisStandaloneConfiguration,GenericObjectPoolConfig genericObjectPoolConfig){
            //1.创建配置构建器,它是基于池的思想管理Jedis连接的
            JedisClientConfiguration.JedisPoolingClientConfigurationBuilder builder = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
            //2.设置池的配置信息对象
            builder.poolConfig(genericObjectPoolConfig);
            //3.创建Jedis连接工厂
            JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration,builder.build());
            //4.返回
            return jedisConnectionFactory;
        }
     @Bean
        //配置spring提供的Redis连接池信息
        public GenericObjectPoolConfig createGenericObjectPoolConfig(){
            //1.创建Jedis连接池的配置对象
            GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
            //2.设置连接池信息
            genericObjectPoolConfig.setMaxTotal(maxActive);
            genericObjectPoolConfig.setMinIdle(minIdle);
            genericObjectPoolConfig.setMaxIdle(maxIdle);
            genericObjectPoolConfig.setMaxWaitMillis(maxWait);
            //3.返回
            return genericObjectPoolConfig;
        }
     @Bean
        //配置Redis标准连接配置对象
        public RedisStandaloneConfiguration createRedisStandaloneConfiguration(){
            //1.创建Redis服务器配置信息对象
            RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
            //2.设置Redis服务器地址,端口和密码(如果有密码的话)
            redisStandaloneConfiguration.setHostName(hostName);
            redisStandaloneConfiguration.setPort(port);
    //        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
            //3.返回
            return redisStandaloneConfiguration;
        }
    
  • RedisTemplate的API

    • opsForValue 操作String
    • opsForHash 操作Hash
    • opsForList 操作List
      tPort(port);
      // redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
      //3.返回
      return redisStandaloneConfiguration;
      }
    
    
  • RedisTemplate的API

    • opsForValue 操作String
    • opsForHash 操作Hash
    • opsForList 操作List
    • opsForSet 操作Set
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值