文章详情

短信预约信息系统项目管理师 报名、考试、查分时间动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JAVA中的事务,事务模块总结

2016-07-09 15:44

关注

JAVA中的事务,事务模块总结


简单的来说,一条SQL执行或则几条SQL一起执行时,我们希望这个SQL要么执行成功后提交,要么执行失败后回滚,这是我们最直观的理解。在上面这句话中,就包含了事务的几个必要属性:"执行成功后提交",意味着持久性;"执行失败后回滚",意味着一致性;"要么成功,要么失败",意味着原子性。他们的具体理解如下:


事务的实现分为两个部分,一个是数据库底层的事务实现,另外一个是基于Spring去实现事务管理。这里主要是讲数据库(mysql-innodb)层面的实现。下面会围绕上面所说的ACID属性来讲mysql的底层实现。

redo日志与原子性、持久性的关系

redo日志是mysql-innodb底层的一个日志文件,主要记录当前数据页的物理修改日志,也就是可以记录事务执行过程中对数据页的更改情况。
如果事务执行了一半数据库宕机了,那么根据redo日志来恢复,可以恢复到事务开始前的数据版本,也就是哪怕宕机了也不存在中间状态,这就是redo日志来保证事务执行的原子性。 持久性的关键点其实在于数据恢复,也就是事务提交后数据的更改永久存在,哪怕宕机了也可以恢复到宕机前的数据。redo日志因为记录的数据页的物理修改情况,所以就可以根据它来恢复数据,保证持久性。
redo日志如此重要,但是它也会有丢失数据的风险,所以mysql的数据安全不能完全指望redo日志去保证,还需要做一些备份处理。具体redo日志的介绍,参考《MySQL技术内幕InnoDB存储引擎》。


undo日志与一致性的关系

undo日志也是mysql-innodb底层的一个日志文件,主要记录事务执行过程中,对具体数据行的修改。可以把它理解成一个数据快照,保存着事务开始前以及执行过程中的各个数据更改前的数据快照。
一致性的理解分为事务执行成功与执行失败两种情况。执行成功要求数据的更改与预期一致,这个其实是上面说的持久性,也就是更改成功后永久存在,我下次再来查数据是存在的;另外就是执行失败需要回滚,这里就是需要用到redo日志了,redo日志相当于一个快照,在事务执行失败后,innodb引擎回去找到对应的快照去做回滚,从而保证了事务的一致性。
redo日志还被用来实现MVCC,也就是常说的"多版本并发控制"。主要也是用的快照属性,在多个事务并发执行时,查询对应的数据时(非锁定读),会直接去查对应的快照,从而实现了一定的隔离性。 另外,redo日志还分为两种类型,更新删除类型和插入类型,这个类型的区别主要是在于记录的内容和删除的方式不同,不过与本篇的主题"事务"没有太大关系,请自行参考《MySQL技术内幕InnoDB存储引擎》。


next_key lock与隔离性的关系

在了解隔离性之前,我们先了解一下,事务并发执行可能带来的一些数据安全性问题:

以上的一些问题,都需要隔离级别来解决对应的问题。事务的隔离性主要分为四种:


Spring的事务管理方式有两种,一种是编程式事务,自己手动去执行事务的一些提交、回滚等操作;还有一种是声明式事务,通过配置或者注解配置好事务管理器,然后由Spring自动管理事务(常用)。


Spring的事务管理主要是有三个接口:

Spring的传播行为主要作用是解决在Spring中各个Service层相互调用时,事务范围划分的问题。例如A方法调用B方法时,事务如何传播。Spring的事务传播行为分为三大类:


就如上文所说,编程式和声明式事务的最大区别就在于事务管理操作的主动与被动。以下Demo是基于上的课程进行的总结,大家可以在文末找到课程的链接,课程是免费的。
编程式事务的实现Demo
配置:PlatformTransactionManager(以下简称manager),datasource与manager绑定后,配置TranscationTemplet。
使用:代码中注入TranscationTemplet 手动执行 transcationTemplet.execute()函数。

声明式事务的实现Demo1:基于TransactionProxyFactoryBean。 配置:配置manager,并与datasource绑定,然后给每个需要事务的业务层配置代理,有N个类就需要配置N个代理。 使用:在代码中使用的时候,只需要注入对应配置的代理类,然后执行函数就可以自动进行事务管理了

声明式事务的实现Demo2:基于AspectJ。 配置:配置manager,并与datasource绑定。然后配置advice与manager绑定,接着配置pointcut,最后将advice与pointcut组成一个aop切面。 使用:代码中不需要做任何的侵入操作,只需要编写符合规则的函数名称,Spring就可以自动生成代理类去进行事务管理

声明式事务的实现Demo3:基于@Transactional注解。 配置:配置manager,并与datasource绑定。最后开启注解事务即可。 使用:代码中使用@Transactional注解修饰需要进行事务管理的类或者函数,Spring就可以自动管理对应的事务操作。

最后对上面四种方式进行总结:


这个问题一般默认都是问的声明式事务的实现原理,我们通常的回答就是基于AOP实现的,也就是动态代理这里在面试的时候,可以和面试官再聊聊代理模式,然后引出动态代理的两种实现方式——JDK动态代理以及CGLIB动态代理。接着说一下这两种实现方式的区别在于是否需要继承接口,最后说清楚为什么JDK动态代理需要实现接口,而CGLIB不需要?——因为动态代理的实现方式和静态代理的方式相同,一个是通过组合方式拿到对应调用,一个是通过继承方式拿到父类调用。关于代理模式,以后也会进行对应的模块总计。

参考书籍及链接:
《MySQL技术内幕InnoDB存储引擎》
《Spring事务管理》

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯