spring-day04

spring-day04

一. 事务

1.事务的作用:

  • 当数据库操作序列中个别操作失败时,提供一种方式使数据库状态恢复到正常状态(A),保障数据库 即使在异常状态下仍能保持数据一致*©(要么操作前状态,要么操作后状态)。
  • 当出现并发访问数据库时,在多个访问间进行相互隔离,防止并发访问操作结果互相干扰(I)。

2. 事务的基本特性有哪些?(面试题)

  • ACID
    • 原子性(Atomicity)
    • 一致性(Consistency)
    • 隔离性(Isolation)
    • 持久性(Durability)

3. 当前的数据出问题的情况?(面试题)

  • **脏读:**读到了另一个事务中未提交的数据

  • **不可重复读:**在一个事务中第一次读取到了一个数据,然后另一个事务对该行数据进行了修改,然后第一个事务再次读取此时数据就发生了变化

  • **幻读/虚读:**第一个事务读取了一次数据,然后另一个事务不断的删除/修改/新增数据,然后第一个事务再次读取数据,此时发现部分数据被删除部分数据被修改部份数据新增

4. 数据库的隔离级别有哪些,分别解决了什么问题(面试题)

  • 读未提交

  • **读已提交:**解决了脏读的问题

  • **可以重复度:**解决了不可重复度的问题

  • **序列化:**解决所有的问题

二. xml实现spring的声明式事务管理

1. 在xml中导入tx的命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:tx="http://www.springframework.org/schema/tx"
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd">

2. 创建DataSourceTransactionManager并且注入一个dataSource对象

    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        	<property name="dataSource" ref="dataSource"/>
    </bean>
  • 该对象只能用于jdbc和mybatis框架

3. 申明事务如何控制

<tx:advice id="txAdvice" transaction-manager="txManager">
  <!--定义控制的事务-->
  <tx:attributes>
      <tx:method name="*" read-only="false"/>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="find*" read-only="true"/>
  </tx:attributes>
</tx:advice>

4. 使用aop把事务和业务结合起来

<aop:config>
    <aop:pointcut id="pt" expression="execution(* com.itheima.service.*Service.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>

三. 声明的具体配置

<tx:method
    name="transfer"
    read-only="false"
    timeout="-1"
    isolation="DEFAULT"
    no-rollback-for=""
    rollback-for=""
    propagation="REQUIRED"
    />
  • 事务名称:name="*"

  • 读写属性:read-only=“false”

  • 隔离级别:isolation=“DEFAULT”

  • 传播机制:propagation=“REQUIRED”

四. 注解实现声明式事务管理

1. 在xml中开启声明式事务观管理

    1. 创建一个管理者
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    1. 开启
    <tx:annotation-driven transaction-manager="txManager"/>
    

2. 在类上/方法上/接口上添加@Transactional注解

    1. 添加在类上或者接口上
    • 类里面的所有的方法/接口里面的所有的方法使用统一的配置

          //对当前方法添加事务,该配置将替换接口的配置
          @Transactional(
              readOnly = false,
              timeout = -1,
              isolation = Isolation.DEFAULT,
              rollbackFor = {},   //java.lang.ArithmeticException.class, IOException.class
              noRollbackFor = {},
              propagation = Propagation.REQUIRED
              )
          public void transfer(String outName, String inName, Double money);
      }
      
    1. 配置在方法上-只有当前的方法使用该配置
    1. 推荐把注解配置在接口上同时接口上和方法上都配置
    1. 需要配置哪些内容
    • readOnly = false,
    • isolation = Isolation.DEFAULT,
    • propagation = Propagation.REQUIRES

3. 纯注解是实现

    1. 在主配置类上添加@EnableTransactionManagement

      @EnableTransactionManagement
      public class SpringConfig {
      }
      
    1. 在某一个配置类中创建一个bean-PlatformTransactionManager

      @Bean
      public PlatformTransactionManager getTransactionManager(DataSource dataSource){
      		return new DataSourceTransactionManager(dataSource);
      }
      

4. redisTemplate

1. redisTemplate在写入数据到redis的时候会对key进行编码,如果换了客户端(jedis)那么就不能获取到数据,此时需要统一key的格式

  • 1.创建Redis配置类

    @PropertySource("redis.properties")
    public class RedisConfig {
    
        @Value("${redis.host}")
        private String hostName;
    
        @Value("${redis.port}")
        private Integer port;
      
        //配置redis访问密码
        //@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;
        }
    }
    
    1. Service层注入RedisTemplate,调用Redis操作数据
    @Service("accountService")
    public class AccountServiceImpl implements AccountService {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        public void save(Account account) {
        }
    
        public void changeMoney(Integer id, Double money) {
            //等同于redis中set account:id:1 100
            redisTemplate.opsForValue().set("account:id:"+id,money);
        }
    
        public Double findMondyById(Integer id) {
            //等同于redis中get account:id:1
            Object money = redisTemplate.opsForValue().get("account:id:" + id);
            return new Double(money.toString());
        }
    }
    

RedisTemplate对象结构

image-20200807200652171

在这里插入图片描述

在这里插入图片描述

2. 常用各种数据类型的具体操作(掌握)

  • redisTemplate.opsForValue().;
  • redisTemplate.opsForHash().;
  • redisTemplate.opsForList().;
  • redisTemplate.opsForSet().;
  • redisTemplate.opsForZSet();

5. 在spring中使用到了哪些设计模式-中级程序员的面试题

1. 装饰

2. 动态代理

3. 策略模式(Strategy Pattern):使用不同策略的对象实现不同的行为方式,策略对象的变化导致行为的 变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值