搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

Spring 事务处理

[复制链接]
查看: 3|回复: 0

1万

主题

1万

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
32664
发表于 2020-1-15 00:19 | 显示全部楼层 |阅读模式
前言:

变乱处置惩罚的本质

在进修变乱处置惩罚前,需要明白一点:
数据库操纵终极都要操纵到JDBC,那末不管上层怎样封装,底层都是挪用Connection的commit,rollback来完成
烦人的变乱处置惩罚:

在一样平常斥地中,数据拜候层(DAO)必定需要举行变乱的处置惩罚,可是我们会发现,变乱处置惩罚的代码凡是是简单的反复的,编写这样的反复代码会浪费大量的时候,所以我们需要找到一种计划可以将这些反复的代码举行抽取,以便与治理保护和复用,
我们的需求:在一系列数据库操纵上的方式上增加额外的变乱处置惩罚代码,让本来的方式中只关注具体的数据处置惩罚,即在本来以及存在的数据库操纵方式上增加额外的变乱处置惩罚逻辑
到这里你应当想到AOP了,没错! 这样的场景下AOP是最好的治理计划;
治理计划:AOP

回首一下Spring的AOP:在结合现在的需求
1.将目标工具(DAO)放入Spring容器
2.奉告Spring你的看护代码是什么(变乱处置惩罚)
3.奉告Spring 哪些方式(DAO的CRUD)要利用那些看护(差此外变乱处置惩罚代码)
4.从Spring中获得代理工具来完成本来的CRUD,代理工具会自动完成变乱处置惩罚
Spring 变乱处置惩罚API

Spring作为框架,需要举行具体的计划,全方位的考虑变乱处置惩罚的各个方面,而不单是简单的帮你尝试commit,rollback;
Spring对变乱处置惩罚举行了笼统界说,构成了一套具体的API结构,以下:
Spring 事务处理  热点新闻 006tNbRwgy1gaw1ii77koj30ro0dxdjy


  • TransactionDefinition:界说变乱的具体属性,如隔离级别,超时设备,传布行为等
  • TransactionStatus: 用于获得当前变乱的状态信息
  • PlatformTransactionMananger: 重要的变乱治理接口,供给三个实现类对应不同场景
典范场景DataSourceTransactionManager操纵Spring JDBC或 iBatis 举行持久化数据时操纵HibernateTransactionManager操纵Hibernate3.0版本 举行持久化数据时操纵JpaTransactionManager操纵JPA举行持久化时 操纵JtaTransactionManager操纵一个JTA实现来治理变乱,跨数据源时操纵留意其散布在差此外jar包中,操纵时按照需要导入对应jar包
变乱的传布行为控制

这是一个新概念可是也很是简单,即在一个尝试sql的方式中挪用了另一个方式时,该怎样处置惩罚这两个方式之间的变乱
Spring界说了7种差此外处置惩罚方式:
常量名寄义PROPAGATION_REQUIRED支持当前变乱。假如 A 方式已经在事 务中,则 B 变乱将间接操纵。否则将 建立新变乱PROPAGATION_SUPPORTS支持当前变乱。假如 A 方式已经在事 务中,则 B 变乱将间接操纵。否则将 以非变乱状态尝试PROPAGATION_MANDATORY支持当前变乱。假如 A 方式没有事 务,则抛出很是PROPAGATION_REQUIRES_NEW将建立新的变乱,假如 A 方式已经在 变乱中,则将 A 变乱挂起PROPAGATION_NOT_SUPPORTED不支持当前变乱,总是以非变乱状态 尝试。假如 A 方式已经在变乱中,则 将其挂起PROPAGATION_NEVER不支持当前变乱,假如 A 方式在变乱 中,则抛出很是PROPAGATION.NESTED嵌套变乱,当外层出现很是则连同内层一路回滚,若外层一般而内部很是,仅回滚内部操纵上述触及的挂起,意义是开启一个自力的变乱,已存在的变乱停息尝试,等待新变乱尝试终了后继续尝试,两个变乱不会相互影响
Spring 整合MyBatis

在起头前我们先完成一个根柢的CURD功用,后续斥地中Spring + MyBatis项目是很常见的,那要将MyBatis整合到Spring中来,要明白一下两者的关系和定位

  • Spring Java斥地框架,其本质是一个工具容器,可以帮助我们完成IOC,DI,AOP
  • MyBatis是一个持久层框架,用于简化对数据库的操纵
将两者整合起来,就是将MyBatis中的工具交给Spring来治理,且将这些工具的依靠也交给Spring来治理;
增加依靠:

Spring 3.0 的斥地在 MyBatis 3.0 官方公布前就竣事了,因而MyBatis社区自己集结斥地者完成了这一部合作作,因而有了mybatis-spring项目,后续Spring也就没有必要在斥地一个新的模块了,所以该jar是MyBatis供给的
  1.     org.mybatis    mybatis-spring    2.0.3  org.mybatis  mybatis  3.5.2  mysql  mysql-connector-java  5.1.44  junit  junit  4.12  org.springframework  spring-context  5.2.2.RELEASE  org.springframework  spring-jdbc  5.2.2.RELEASE  org.springframework  spring-tx  5.2.2.RELEASE  org.springframework  spring-test  5.2.2.RELEASE  org.aspectj  aspectjweaver  1.8.0
复制代码
SM根柢操纵

设备文件
  1.                                                                               
复制代码
jdbc.properties:
  1. driver = com.mysql.jdbc.Driverurl = jdbc:mysql:///SMDB?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=falseusr = rootpassword = adminlocation = /Users/jerry/.m2/repository/mysql/mysql-connector-java/8.0.17/mysql-connector-java-8.0.17.jar
复制代码
测试代码:
  1. @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Test1 {    @Autowired    private StudentMapper studentMapper;    @Test    public  void test(){        Student student = studentMapper.selectByPrimaryKey(1);        System.out.println(student);    }}
复制代码
编码式变乱

编码式变乱,即在源代码中加入 变乱处置惩罚的代码, 即commit,rollback等,这黑白常原始的做法仅作为了解
纯手动治理变乱

设备文件:
  1.                                        
复制代码
测试代码:
  1. @Autowiredprivate StudentMapper studentMapper;@Autowiredprivate DataSourceTransactionManager manager;@Autowiredprivate DefaultTransactionDefinition definition;@Testpublic  void test(){    TransactionStatus transactionStatus = manager.getTransaction(definition);    try{        Student student = studentMapper.selectByPrimaryKey(1);        System.out.println(student);        student.setAge(201);        studentMapper.updateByPrimaryKey(student);              int i = 1/0;        manager.commit(transactionStatus);    }catch (Exception e){        e.printStackTrace();        manager.rollback(transactionStatus);    }}
复制代码
上述代码仅用于测试变乱处置惩罚的有用性;
我们已经在Spring中设备了MyBatis,并举行了变乱处置惩罚,可是没有治理反复代码的题目
操纵变乱模板

变乱模板道理是将要尝试的具体代码交给模板,模板会在尝试这写代码的同时处置惩罚变乱,当这写代码出现很是时则自动回滚变乱,以此来简化钞缮
设备文件:
  1.       
复制代码
测试代码:
  1. public class Test2 {    @Autowired    private StudentMapper studentMapper;    @Autowired    private TransactionTemplate transactionTemplate;    @Test    public  void test(){        transactionTemplate.execute(new TransactionCallback() {            public Object doInTransaction(TransactionStatus transactionStatus) {                Student student = studentMapper.selectByPrimaryKey(1);                System.out.println(student);                student.setAge(1101);                studentMapper.updateByPrimaryKey(student);//                int i = 1/0;                return null;            }        });    }}
复制代码
可以看到变乱模板要求供给一个实现类来提交原始的数据库操纵给模板,从而完成变乱代码的增强
不管是纯手动治理照旧操纵模板,仍然存在大量与营业无关的反复代码,这也是编码式变乱最大的题目;
声明式变乱

即不需要在本来的营业逻辑代码中加入任何变乱相关的代码,而是经过xml,大要注解的方式,来告诉框架,哪些方式需要增加变乱处置惩罚代码,让框架来完成在原始营业逻辑前后增加变乱处置惩罚的代码(经过AOP),这也是AOP操纵较多的场景之一;
基于tx称号空间的设备

设备文件:
需要引入aop和tx称号空间
  1.                                                                                     
复制代码
tx:method属性:
属性名寄义name婚配的方式称号isolation变乱隔离级别read-only能否采取优化的只 读变乱timeout超时rollback-for需要回滚的很是类propagation传布行为no-rollback-for不需要回滚的很是类Service:
  1. @Servicepublic class StudentService {    @Autowired    private StudentMapper studentMapper;    public Student getStudent(int id ){        return studentMapper.selectByPrimaryKey(id);    }    public void update(Student student){        studentMapper.updateByPrimaryKey(student);        int i  = 1/0;    }}
复制代码
测试代码:
  1. @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext3.xml")public class Test3 {    @Autowired    StudentService studentService;    @Test    public void test(){        Student student = studentService.getStudent(1);        System.out.println(student);        student.setAge(8818);        studentService.update(student);    }}
复制代码
夸大:变乱增强应当利用到Service层,即营业逻辑层,应为一个营业方式大要触及多个数据库操纵,当某个操纵碰到很是时需要将全数操纵全数回滚
基于注解的设备

Spring固然也支持采取注解形式来处置惩罚变乱
开启注解变乱支持:
  1.                                  
复制代码
Service中增加方式:
  1. @Transactional(propagation = Propagation.REQUIRED,readOnly = false)public void transactionTest(){    Student student = getStudent(1);    student.setAge(1);    update(student);    int i = 1/0;    student.setName("jack");    update(student);}//固然注解上的参数都是可选的采取默许值即可
复制代码
测试代码
  1. @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext4.xml")public class Test4 {    @Autowired    StudentService studentService;    @Test    public void test(){        studentService.transactionTest();    }}
复制代码
你大要会以为注解的方式比xml设备简单的多,可是考虑一下,当你的项目出格大,触及的表很多的时候呢,你大要需要些很多很多的注解,假定前期需要点窜某些属性,还得一个个改;
所以大项目倡议采取XML,小项目操纵注解也ok;
道理简述

声明式变乱其底层用的照旧AOP,你完全可以自己手动的设备每个环节,如目标,看护,切面,代理等,这能让你更清楚的明白每一行代码背后到底做了什么变乱;
设备文件:
  1.                                                                         PROPAGATION_REQUIRED                                                                                                
复制代码
测试代码:
  1. @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext5.xml")public class Test5 {    @Autowired    @Qualifier("orderService")    StudentService studentService;    @Test    public void test(){        Student student = studentService.getStudent(1);        student.setAge(1);        studentService.update(student);    }}
复制代码
免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 全椒百姓网-全椒知名**,发布及时新鲜的全椒新闻资讯 生活信息 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表