Spring5之事务

Spring5之事务,第1张

Spring5之事务

事务概念
    1.什么是事务
        (1)是数据库 *** 作最基本的单元,逻辑上的一组 *** 作,要么都成功,要么全失败
        (2)典型场景:银行转账
    2.事务特性
        (1)原子性(要么都成功,一个失败都失败)
        (2)一致性(总量相同)
        (3)隔离性(多个事务之间互不影响)
        (4)持久性(比如数据发生改变是永久性的)
        
        
事务 *** 作(环境搭建)
    1.创建数据库表,添加记录
    2.创建service类,dao接口和实现类,完成对象创建和关系注入
        (1)在service注入dao,在dao实现类jdbctemplate,在jdbctemplate注入datasource
    3.在dao创建加钱和少钱的方法,在service创建转账的方法    
        (1)dao里
        public interface UserDao {
            public void addMoney();
            public void reduceMoney();

        }
        (2)daoimpl里
            @Autowired
            private JdbcTemplate jdbcTemplate;
            //少钱
            @Override
            public void reduceMoney() {
                String sql = "update t_account set money=money-? where username=?";
                jdbcTemplate.update(sql, 100, "lucy");

            }
            //多钱
            @Override
            public void addMoney() {
                String sql = "update t_account set money=money+? where username=?";
                jdbcTemplate.update(sql, 100, "mary");
            }
        (3)service里
            @Autowired
            private UserDao userDao;

            //转账方法
            public  void  accountMoney() {
                //lucy少一百
                userDao.reduceMoney();
                //mary多一百
                userDao.addMoney();
            }
        (4)测试
            @Test
            public  void test() {
                ApplicationContext context =
                        new ClassPathXmlApplicationContext("bean1.xml");
                UserService userService = context.getBean("userService", UserService.class);
                userService.accountMoney();
            }
        
    4.如果代码在执行过程中出现异常
        出现钱少了但另一个人钱没有增加的问题
            //转账方法
            public  void  accountMoney() {
                //lucy少一百
                userDao.reduceMoney();
                //模拟异常
                int i = 10 / 0;
                //mary多一百
                userDao.addMoney();
            }
        (1)用事务来解决,都成功才成功
        (2)事务 *** 作过程(编程式,但通常使用声明式)
                try {
                    //第一步开启事务


                    //第二步开启业务 *** 作
                    //lucy少一百
                    userDao.reduceMoney();
                    //模拟异常
                    int i = 10 / 0;
                    //mary多一百
                    userDao.addMoney();

                    //第三步没有发生异常,提交事务
                } catch (Exception e) {
                    //第四步出现异常,事务回滚
                }
        

事务 *** 作(Spring事务管理介绍)
    1.事务一般添加到service(业务逻辑层)
    2.在Spring里进行事务管理 *** 作
        (1)有两种方式:编程式和声明式事务管理(一般使用后者)

    3.    声明式事务管理
        (1)基于xml配置文件
        (2)基于注解方式(通常使用)
        
    4.在Spring进行声明式的事务管理,底层使用aop原理
    5.Spring事务管理API
        (1)提供了一个接口,代表事务管理器PlatformTransactionManager
        这个接口为不同的框架提供了不同的实现类
        jdbc模板这里使用的是DataSourceManager实现类
        
        
        
Spring声明式事务管理(基于注解)        
    1.在xml文件中配置事务管理器    
        
        
            
            
        

    2.在xml文件中开启事务注解
        (1)引入名称空间tx
        (2)
            
    3.在service类(或方法)上面添加事务注解    
        (1)@Transactional,这个注解可以添加到类上或者方法上
        (2)如果把注解添加到类上,则类的所有方法都添加事务
        (3)如果添加到方法上,只为方法添加事务
        (4)我遇到了的问题(视频里没有):
            在过程中遇到了事务注解失效的问题,
            由于数据库里的表默认为myisam,不支持事务 *** 作,需要通过
            ALTER TABLE t_account ENGINE = INNODB;设置成innodb


Spring声明式事务管理(参数配置)
    1.@Transactional()括号里参数配置
    2.(1)propagation:事务传播行为
            多事务方法调用,过程中事务如何管理
            事务方法指对数据库表数据进行变化的 *** 作(比如查询不属于)
            
            举例有一个add方法上有事务,并且在内部调用update方法
            @Transactional
            public void add(){update();}       public void update(){}
            
            Spring框架事务传播行为有七种:
                (1)REQUIRED:如果add方法本身有事务,调用update方法后,update也使用add当前的事务
                                如果add方法没有事务,调用update方法后,创建新事务
                (2)REQUIRED_NEW :使用add方法调用update方法,无论add是否有事务都会创建新的事务
                 还有多种不一一例举
            @Transactional(propagation = Propagation.REQUIRED)
            
      (2)ioslation:事务隔离级别
            (1)有隔离性多事务 *** 作之间才不会受影响
            (2)不考虑隔离性会出现三个读的问题:脏读、不可重复读、虚读
            (3)脏读:一个未提交事务读取到了另一个未提交事务的数据
                例如两个人修改一条记录,一个人修改完的数据被另一个人看见了,
                但数据进行了事务回滚,导致数据变化,读取的数据不准确。
            (4)不可重复读:一个未提交事务读取到另一个提交事务的修改数据
                (正常事务之间没有影响,只有提交事务之后才能读取到新数据)
            (5)虚读:一个未提交事务读取到另一个提交事务的添加数据
            (6)设置隔离性可以解决以上问题(mysql中默认为REPEATABLE READ)
                    READ UNCOMMITTED  三个问题都不能解决
                    READ COMMITTED    能解决脏读问题
                    REPEATABLE READ  不能解决虚读(幻读)问题
                    SERIALIZABLE   都能解决
                @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
      
      (3)timeout:超时时间
            (1)事务设置必须在多长时间内提交,超时则会回滚
            (2)默认值是-1(表示永不超时),秒为单位
      
      (4)readonly:是否只读
            (1)读:查询。写:添加修改删除
            (2)默认值为false,表示读写都可以
            (3)设置值为true,表示只读
            
      (5)rollbackfor:回滚
            (1)设置出现哪些异常进行事务回滚
            
      (6)norollbackfor:不回滚
            (1)设置出现哪些异常不进行回滚
        
        
Spring声明式事务管理(基于xml配置文件)    
    1.在xml文件中
    第一步配置事务管理器
    第二步配置通知(增强的部分在这就是事务)
    第三步配置切入点(方法)和切面(事务加到方法的过程)
        
        
            
            
        

        
        
        
            
            
            
                
            
            
            

        

        
        
        
            
            
            
            
        
        
        
Spring声明式事务管理(完全注解开发)    
    1.配置类
        @Configuration//表示作为配置类
        @ComponentScan(basePackages = "com.xlj")//开启组件扫描
        @EnableTransactionManagement//开启事务

        public class txconfig {

            //创建数据库连接池
            @Bean
            public DruidDataSource getDruidDataSource() {
                DruidDataSource dataSource = new DruidDataSource();
                dataSource.setDriverClassName("com.mysql.jdbc.Driver");
                dataSource.setUrl("jdbc:mysql:///user_db");
                dataSource.setUsername("root");
                dataSource.setPassword("root");
                return dataSource;
            }

            //创建jdbctemplate对象
            @Bean
            public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
                //到ioc容器中根据类型找到datasource
                JdbcTemplate jdbcTemplate = new JdbcTemplate();
                //注入datasource
                jdbcTemplate.setDataSource(dataSource);
                return jdbcTemplate;
            }

            //创建事务管理器对象
            @Bean
            public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
                DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
                dataSourceTransactionManager.setDataSource(dataSource);
                return dataSourceTransactionManager;
            }
        }

    2.测试
        @Test
        public  void test2() {
            ApplicationContext context =
                    new AnnotationConfigApplicationContext(TxConfig.class);
            UserService userService = context.getBean("userService", UserService.class);
            userService.accountMoney();
        }

    
        
        
        
        
        

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4668789.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存