@Transactional 事务注解

Haskell
• 阅读 3005

前言

“不积跬步无以至千里,不积小流无以成江海。”

在进团队之前总以为掌握知识可以速成,记住了就好了,但是随着一步步的前行,发现知识真的是一点一滴积累起来的。
发现项目中好多用到@Transactional注解的地方,正好以后还有用到这个注解的地方,于是找时间看了一下事务注解的释义和使用。

事务概念以及特性

概念

事务就是「一组原子性的SQL查询」,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询。如果其中有任何一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。事务用来管理 insert,update,delete 语句。

特性

事务是恢复和并发控制的基本单位。

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。

一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

@Transactional 事务注解的部分属性

@Transactional 注解的属性信息
属性名 说明
name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
propagation 事务的传播行为,默认值为 REQUIRED。
isolation 事务的隔离度,默认值采用 DEFAULT。
timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。

@Transactional 注解也可以添加到类级别上。当把@Transactional 注解放在类级别时,表示所有该类的公共方法都配置相同的事务属性信息。
需要注意的是:
@Transactional 只能应用到 public 方法才有效

回滚
回滚(Rollback)指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为。回滚包括程序回滚和数据回滚等类型。

删除由一个或多个部分完成的事务执行的更新。为保证应用程序、数据库或系统错误后还原数据库的完整性,需要使用回滚。

回滚泛指程序更新失败, 返回上一次正确状态的行为。

在默认设置下,事务只在出现运行时异常(runtime exception)时回滚,而在出现受检查异常(checked exception)时不回滚(这一行为和EJB中的回滚行为是一致的)。
不过,可以声明在出现特定受检查异常时像运行时异常一样回滚。同样,也可以声明一个事务在出现特定的异常时不回滚,即使特定的异常是运行时异常。

回滚对程序员意味着非常严重的失误。所以回滚次数往往与程序员的薪金直接联系。主流互联网公司通常都将回滚定位为最严重的事故。

隔离级别

事务的隔离级别定义一个事务可能受其他并发务活动活动影响的程度,可以把事务的隔离级别想象为这个事务对于事物处理数据的自私程度。

在一个典型的应用程序中,多个事务同时运行,经常会为了完成他们的工作而操作同一个数据。并发虽然是必需的,但是会导致以下问题:

1. 脏读(Dirty read)
在事务A修改数据之后提交数据之前,这时另一个事务B来读取数据,如果不加控制,事务B读取到A修改过数据,之后A又对数据做了修改再提交,则B读到的数据是脏数据,此过程称为脏读Dirty Read。
2. 不可重复读(Nonrepeatable read)
一个事务内在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了变更、或者某些记录已经被删除了。

3. 幻读(Phantom reads)
事务A在按查询条件读取某个范围的记录时,事务B又在该范围内插入了新的满足条件的记录,当事务A再次按条件查询记录时,会产生新的满足条件的记录(幻行 Phantom Row)

不可重复读与幻读有什么区别?

不可重复读的重点是修改:在同一事务中,同样的条件,第一次读的数据和第二次读的「数据不一样」。(因为中间有其他事务提交了修改)
幻读的重点在于新增或者删除:在同一事务中,同样的条件,第一次和第二次读出来的「记录数不一样」。(因为中间有其他事务提交了插入/删除)

在理想状态下,事务之间将完全隔离,从而可以防止这些问题发生。然而,完全隔离会影响性能,因为隔离经常涉及到锁定在数据库中的记录(甚至有时是锁表)。完全隔离要求事务相互等待来完成工作,会阻碍并发。因此,可以根据业务场景选择不同的隔离级别。

总结

知识能不能理解,主要看讲解的人能不能让别人理解,看了一些关于事务的博客,发现水平真的参差不齐,有的说了半天也不知道在说啥,我的博客也处在这个水平,但是参考了那些高水平的博客,化抽象为具体,更易于让人理解,毕竟对于计算机来说,抽象的东西太多了,容易让人懂就吸引人,之前我是肯定读不下去这些资料的,看了半天看不懂,就和大部分老师讲课似的只讲概念,学生就算有兴趣也给磨没了,现在发现自己不是没兴趣,而是有兴趣也给磨没了,在此感谢我的团队,感谢潘老师,让我找到并且一直保持着兴趣。

引用

面试官:你说对 MySQL 事务很熟?那我问你 10 个问题
MySQL 事务
有关Spring事务,看这一篇就足够了

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
spring事物管理之传播行为和隔离级别
大家在使用spring的注解式事务管理时,对事务的传播行为和隔离级别可能有点不知所措,下边就详细的介绍下以备方便查阅。事物注解方式:@Transactional当标于类前时,表示类中所有方法都进行事物处理例子:@TransactionalpublicclassTestServiceBeanimplementsTest
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Stella981 Stella981
3年前
Spring 事务失效的 8 大场景,面试官直呼666...
!(https://oscimg.oschina.net/oscnet/c5b4fcf737f248db8060e0f7c009f6c8.jpg)前几天发了一篇文章里面有一个关于事务失效的问题:用Spring的@Transactional注解控制事务有哪些不生效的场景?其中有个热心粉丝留言分享了下,我觉得总结得有点经验
Wesley13 Wesley13
3年前
@Transactional 回滚不生效原因
事务的管理方式有两种,第一种是编程式事务管理,需要将数据库的自动提交等取消,并且需要自己编写事务代码,第二种则是声明式事务管理模式,spring利用springAOP特性编写了注解即题目中所提到的方式来管理事务,避免开发人员编写大量的事务代码。一、特性先来了解一下@Transactional注解的特性吧,可以更好排查问题1\.service类
Wesley13 Wesley13
3年前
@Transactional注解失效的解决方案
一、前言  开发中我们经常使用@Transactional注解来启用Spring事务管理,但是如果使用方法不当,会遇到注解不生效该事务回滚的地方却没有回滚的问题。总结下一般是以下几个原因:1.@Transactional注解只能应用到public可见度的方法上。如果应用在protected、private或者p
Wesley13 Wesley13
3年前
JPA之SQL修改语句
昨天遇到一个小问题,是使用JPA的注解对数据进行修改操作对:@Transactional@Modifying@Query("updatePersonpsetp.name?1")voidupdateById(Stringname);这里要注意的是@Transactional注解和@
Wesley13 Wesley13
3年前
FPGA设计经验总结
1.1FPGA设计经验总结1.1.1本节目录1)本节目录;2)本节引言;3)FPGA简介;4)FPGA设计经验;5)结束语。1.1.2本节引言“不积跬步,无以至千里;不积小流,无以成江海。就是说:不积累一步半步的行程,就没有办法达到千里之远;不积累
Easter79 Easter79
3年前
Spring注解@Resource和@Autowired区别对比、spring扫描的默认bean的Id、程序获取spring容器对象
\注解扫面的bean的ID问题0.前提需要明白注解扫描出来的bean的id默认是类名首字母小写,当然可以指定id:
Wesley13 Wesley13
3年前
Java Annotation详解 理解和使用Annotation
系统中用到了java注解:查了一下如何使用注解,到底注解是什么;(1)创建方法:MsgTraceJavaClass在CreateNewClass中:name:输入MsgTrace;Kind:Annotation;就可以了;public@interfaceMsgTrace{String
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
五年规划 五年规划
2年前
纪念标题-五年规划
1.国家有五年计划,自己也要有5年规划。或者是3年规划。小船好调头,随时调整方向。不积跬步无以至千里,加油。