博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 框架的事务管理
阅读量:7188 次
发布时间:2019-06-29

本文共 7271 字,大约阅读时间需要 24 分钟。

1. Spring 框架的事务管理相关的类和API

  • PlateformTransactionManager 接口: 平台事务管理器(真正管理事务的类);
  • TransactionDefinition 接口: 事务定义信息(事务的隔离级别,传播行为,超时,只读等);
  • TransactionStatus 接口: 事务的状态;
  • 平台事务管理器真正管理事务对象,根据事务定义信息(TransactionDefinition)进行事务管理,在管理事务
    中产生的一些状态记录到TransactionStatus中;

1.1 PlateformTransactionManager 接口中实现类和常用的方法

  1. 接口的实现类
    • 如果使用 Spring 框架的JDBC模板或者MyBatis框架,需要选择DataSourceTransactionManager实现类;
    • 如果使用的是 Hibernate 框架,需要选择HibernateTransactionManager实现类;
  2. 该接口的常用方法
    • void commit(TransactionStatus status)
    • TransactionStatus getTransaction(TransactionDefinition definition)
    • void rollback(TransactionStatus status)

1.2 TransactionDefinition

  1. 事务隔离级别的常量
    • static int ISOLATION_DEFAULT: 采用数据库的默认隔离级别;
    • static int ISOLATION_READ_UNCOMMITTED
    • static int ISOLATION_READ_COMMITTED
    • static int ISOLATION_REPEATABLE_READ
    • static int ISOLATION_SERIALIZABLE
  2. 事务的传播行为常量(一般使用默认值)
    • 事务的传播行为:解决的是业务层之间的方法调用!
    • 保证 A,B 在同一个事务中:
      • PROPAGATION_REQUIRED(默认值): A中有事务,使用A中的事务;如果没有,B会开启一个新的事务,
        将A包含进来(保证A,B在同一个事务中);
      • PROPAGATION_SUPPORTS: A中有事务,使用A中的事务;如果A中没有事务,那么B也不使用事务;
      • PROPAGATION_MANDATORY: A中有事务,使用A中的事务; 如果A中没有事务,抛出异常;
    • 保证 A,B 没有在同一个事务中:
      • PROPAGATION_REQUIRES_NEW: A中有事务,将A中的事务挂起,B创建一个新的事务,
        (保证A,B不在同一个事务中);
      • PROPAGATION_NOT_SUPPORTED: A中有事务,将A中的事务挂起;
      • PROPAGATION_NEVER: A中有事务,抛出异常;
    • PROPAGATION_NESTED: 嵌套事务,当 A 执行之后,就会在这个位置设置一个保存点,如果B没有问题,
      执行通过;如果B出现异常,根据需求回滚(可以回滚到保存点或最初始的状态);

1222878-20171024171245191-1637070645.png

2. 搭建事务管理转账案例的环境

2.1 导入 jar 包

  • Spring 框架的基本开发包(6个);
  • Spring 的传统AOP的开发包
    • spring-aop-4.3.10.RELEASE
    • org.aopalliance-1.10.0 (在 Spring 依赖包中)
  • aspectJ 的开发包
    • org.aspectj.weave-1.6.8.RELEASE.jar (在 Spring 依赖包中)
    • spring-aspects-4.3.10.RELEASE.jar
  • JDBC 模板所需 jar 包
    • mysql-connector-java.jar: MySql 驱动包;
    • Spring-jdbc.jar;
    • Spring-tx.jar: Spring 事务包;
  • c3p0 的 jar 包: com.mchange.v2.c3p0-0.9.1.2.jar

2.2 创建对应的包结构和类

  • com.itheima.demo
    • AccountService
    • AccountServiceImpl
    • AccountDao
    • AccountDaoImpl
// AccountDao.java    public class AccountDao {        // 扣钱        public void outMoney(String out, double money);        // 加钱        public void inMoney(String in, double money);    }// AccountService.java    public class AccountService{        public void pay(String out,String in, double money);    }// AccountDaoImpl.java    // 第一种方式, 使用 jdbc 模板类    public class AccountDaoImpl implements AccountDao{        // 使用 jdbc 模板操作数据库        // 在配置文件中注入 jdbcTemplate 对象        private JdbcTemplate jdbcTemplate;        public void setJdbcTemplate(JdbcTemplate jdbcTemplate){            this.jdbcTemplate = jdbcTemplate;        }        // 扣钱        public void outMoney(String out, double money){            jdbcTemplate.update(sql,args);        }        // 加钱        public void inMoney(String out, double money){            jdbcTemplate.update(sql,args);        }    }    // 第二种方式, 继承 JdbcDaoSupport类, 该类中包含 jdbcTemplate,并且提供了 set方法    //           applicationContext.xml 中仍需要注入 jdbcTemplate 对象    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{        // 扣钱        public void outMoney(String out, double money){            this.getJdbcTemplate().update(sql,args);        }        // 加钱        public void inMoney(String in, double money){            this.getJdbcTemplate().update(sql,args);        }    }    // 第三种方式: applicationContext.xml 中无需注入 jdtcTemplate 对象    //           只需要注入连接池对象,    // JdbcDaoSupport 类内部,在 jdbcTemplate 对象为 null 时, 根据连接池创建 jdbcTemplate 对象    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{        // 扣钱        public void outMoney(String out, double money){            this.getJdbcTemplate().update("UPDATE t_account SET"                                +"money = money - ? WHERE name = ?",money,out);        }        // 加钱        public void inMoney(String in, double money){            this.getJdbcTemplate().update("UPDATE t_account SET"                                +"money = money - ? WHERE name = ?",money,in);        }    }// AccountServiceImpl.java    public class AccountServiceImpl implements AccountService{        private AccountDao accountDao;        public void setAccountDao(AccountDao accountDao){            this.accountDao = accountDao;        }        // 实现转账功能        public void pay(String out, String in, double money){            accountDao.outMoney(out,money);            accountDao.inMoney(in,money);        }    }// 测试类    @RunWith(SpringJUnit4ClassRunner.class)    @ContextConfiguration("classpath:applicationContext.xml")    public class Demo{        @Resource(name="accountService")        private AccountServiceImpl accountService;        @Test        public void fun(){            // 测试支付方法            accountService.pay("张三","李四",100);        }    }

2.3 applicationContext.xml

2.4 Spring 框架事务管理的分类

  1. Spring 的编程式事务管理(不推荐使用)
    • 通过手动编写代码的方式完成事务的管理;
  2. Spring 的声明式事务管理(底层采用AOP的技术)
    • 通过一段配置的方式完成事务的管理;
2.4.1 编程式的事务管理
  1. 手动编程的方式来管理事务,需要使用 TransactonTemplate模板类;
// 具体步骤// 1. 配置一个事务管理器//    Spring 框架使用 PlatFormTransactionManager 接口来管理事务,需要使用到它的实现类
// 底层操作事务的是 connection, 该对象存放在连接池 // 事务管理器管理事务,需要从连接池中获取 connection 对象
// 2. 配置事务管理的模板
// 3. 在需要进行事务管理的类中,注入事务管理的模板// 备注: 事务需要在业务层开启
// 4. 在业务层使用模板管理事务public void AccountServiceImpl implements AccountService{ private AccountDao accountDao; public void setAccountDao(AccountDao accountDao){ this.accountDao = accountDao; } // 注入事务模板对象 private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate){ this.transactionTemplate = transactionTemplate; } // 实现转账功能 public void pay(final String out, final String in, final double money){ transactionTemplate.execute(new TransactionCallbackWithoutResult(){ protected void doInTransactionWithoutResult(TransactionStatus status){ // 扣钱 accountDao.outMoney(out,money); // 异常 int a = 10 / 0; // 加钱 accountDao.inMoney(in,money); } }); }}
2.4.2 声明式事务管理
  1. 声明式事务管理:即通过配置文件来完成事务管理(AOP 思想)
    • 基于AspectJ的XML方式;(重点掌握)
    • 基于AspectJ的注解方式;(重点掌握)
基于AspectJ的XML方式
// applicationContext.xml// 1. 配置一个事务管理器//    Spring 框架使用 PlatFormTransactionManager 接口来管理事务,需要使用到它的实现类
// 底层操作事务的是 connection, 该对象存放在连接池 // 事务管理器管理事务,需要从连接池中获取 connection 对象
// 2. 配置事务增强(通知)
// 3. 配置 AOP 切面// 备注: 如果是自定义的切面,使用
标签, 如果是系统自带的,使用
标签
// 4. 持久层配置
基于AspectJ的注解方式(重点掌握,这是最简单的方式)
// 1. 配置事务管理器
// 2. 开启注解事务
// 3. 在业务层上添加一个注解: @Transactional// AccountServiceImpl.java // 如果在这个类上添加注解, 类中的所有方法全部都有事务 @Transactional public class AccountServiceImpl implements AccountService{ private AccountDao accountDao; public void setAccountDao(AccountDao accountDao){ this.accountDao = accountDao; } // 实现转账功能 // 如果在方法上添加,只有该方法有事务 @Transactional public void pay(String out, String in, double money){ accountDao.outMoney(out,money); accountDao.inMoney(in,money); } }

参考资料

转载于:https://www.cnblogs.com/linkworld/p/7724625.html

你可能感兴趣的文章
《七周七数据库》一一第1章 概述
查看>>
【深度学习之美】神经网络不胜语, M-P模型似可寻(入门系列之三)
查看>>
《网页美工设计Photoshop+Flash+Dreamweaver从入门到精通》——1.6 网页配色安全
查看>>
【双11背后的技术】双11晚会背后的技术
查看>>
解压rabbitmq安装文件出错问题
查看>>
"飞猪"如何靠着一群"猪队友",实现单日21亿交易额?
查看>>
笔记 - 2、HTML - 表格
查看>>
vue中使用高德地图搭建实时公交应用(地图 + 附近站点+线路详情 + 输入提示+换乘详情)...
查看>>
Vue 2.5发布在即 将全面支持TypeScript
查看>>
怎么实现三列布局(左侧和右侧宽度固定,中间自适应)
查看>>
DTJQP
查看>>
小猿圈python之Django和Flask比较?
查看>>
Android Studio 代码模版,一键生成 MVP 类
查看>>
Nginx入门(1)服务器的安装和配置
查看>>
Git让你从入门到精通,看这一篇就够了!
查看>>
黑苹果组装指南
查看>>
axios Post请求 .Net Core中的接口以及FromBody特性和FromForm特性的使用
查看>>
大数据BigData之如何配置hive连接mysql,把mysql作为元数据库?
查看>>
拿下阿里、头条、滴滴的offer后谈谈面试经验(上)
查看>>
RecyclerView相关问题记录
查看>>