事务是指对系统进行的一组操作,为了保证系统的完整性,事务需要具有ACID特性,具体如下:

1. 原子性(Atomic)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 一个事务包含多个操作,这些操作要么全部执行,要么全都不执行。实现事务的原子性,要支持回滚操作,在某个操作失败后,回滚到事务执行之前的状态。
回滚实际上是一个比较高层抽象的概念,大多数DB在实现事务时,是在事务操作的数据快照上进行的(比如,MVCC),并不修改实际的数据,如果有错并不会提交,所以很自然的支持回滚。
而在其他支持简单事务的系统中,不会在快照上更新,而直接操作实际数据。可以先预演一边所有要执行的操作,如果失败则这些操作不会被执行,通过这种方式很简单的实现了原子性。
针对同一个事务

这个过程包含两个步骤
A: 800 - 200 = 600
B: 200 + 200 = 400

原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作

2. 一致性(Consistency)
事务前后数据的完整性必须保持一致。
一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。事务的一致性决定了一个系统设计和实现的复杂度。事务可以不同程度的一致性:
强一致性:读操作可以立即读到提交的更新操作。
弱一致性:提交的更新操作,不一定立即会被读操作读到,此种情况会存在一个不一致窗口,指的是读操作可以读到最新值的一段时间。
最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有错误发生,不一致窗口的大小依赖于:通信延迟,系统负载等。
其他一致性变体还有:
单调一致性:如果一个进程已经读到一个值,那么后续不会读到更早的值。
会话一致性:保证客户端和服务器交互的会话过程中,读操作可以读到更新操作后的最新值。

操作前A:800,B:200
操作后A:600,B:400

一致性表示事务完成后,符合逻辑运算
3. 隔离性(Isolation)
并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。
两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据。

按照箭头顺序,如果没有隔离性,那么按照箭头顺序就可能会出现脏读,也就是A:800-100,B:200+100.
再看一个明了例子:
  小明和小芳各自有一本作业本,如果他们同时去写作业,这时他们都可以在各自作业本上写作业是相互不影响的。但是如果他们两个人只有一本作业本,但是他们都想去写作业怎么办,那么就这个时候就只能等一个人先写完作业后,另外一个人才能写,要不然两个人同时在同一个作业本上写作业,那么肯定会乱套。所以这种两个事物操作同一个对象必须隔离开来不能相互影响的特性称为事务的隔离性。
在事务并发操作时,可能出现的问题有:
脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。

不可重复读:在同一个事务中,两条相同的查询语句的查询结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这会导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。

幻读:同一个事务内,两条相同的查询语句的查询结果应该相同。但是,如果另一个事务同时提交了新数据,当本事务再更新时,就会惊奇地发现这些新数据,貌似之前读取到的数据是“鬼影”一样的幻觉。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,解决方法有两个:
1、将事务隔离级别设置为serializable可以避免幻读现象,但串行化导致无并发,效率降低。
2、保持事务的隔离级别RR(可重复读)不变,利用间隙锁的特点,对查询结果集施加共享锁或者排他锁。

幻读现象与不可重复读现象不同之处在于,幻读现象读不到其他事务已经提交的数据,而不可重复读现象读到的是其他事务已经提交的数据。

上述事务机制不能很好解释幻读现象读取不到其他事务已经提交的数据现象,我们通过一个例子来验证:

事务的隔离级别从低到高有:
Read Uncommitted:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
Repeated Read:在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。
通常,在工程实践中,为了性能的考虑会对隔离性进行折中。
4. 持久性(Durability)
事务提交后,对系统的影响是永久的。
表示事务结束后的数据不随着外界原因导致数据丢失

操作前A:800,B:200
操作后A:600,B:400
如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:800,B:200
如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:600,B:400

最后我们看下一个问题:spring的事务是什么?与数据库的事务是否一样?

  之前一直觉得事务只针对于数据库当中,5种隔离级别,7种传播行为,后来才发现这是针对Spring的,对数据库来说隔离级别只有4种,Spring多了一个DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.

  总的来说,本质上其实是同一个概念,spring的事务是对数据库的事务的封装,最后本质的实现还是在数据库,假如数据库不支持事务的话,spring的事务是没有作用的。数据库的事务说简单就只有开启,回滚和关闭,spring对数据库事务的包装,原理就是拿一个数据连接,根据spring的事务配置,操作这个数据连接对数据库进行事务开启,回滚或关闭操作。但是spring除了实现这些,还配合spring的传播行为对事务进行了更广泛的管理.其实这里还有个重要的点,那就是事务中涉及的隔离级别,以及spring如何对数据库的隔离级别进行封装。事务与隔离级别放在一起理解会更好些。

四种隔离级别,从程度从低到高依次是读未提交,读已提交,可重复读、串行化。隔离级别越大安全性越高,同时效率也越低,如果设置串行化,那就不存在并发操作了。四种隔离级别对于上述并发下可能出现的三个问题的控制情况可用一张图来描述:

spring事务与数据库事务与锁之间的关系?

  spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁;那么事务的隔离级别与锁有什么关系呢?本人认为事务的隔离级别是通过锁的机制实现的,事务的隔离级别是数据库开发商根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数据库的隔离级别定义为某一级别后如仍不能满足要求,我们可以自定义 sql 的锁来覆盖事务隔离级别默认的锁机制。

spring事务实际使用AOP拦截注解方法,然后使用动态代理处理事务方法,捕获处理过程中的异常,spring事务其实是把异常交给spring处理;

spring事务只有捕获到异常才会终止或回滚,如果你在程序中try/catch后自己处理异常而没有throw,那么事务将不会终止或回滚,失去事务本来的作用;

spring事务会捕获所有的异常,但只会回滚数据库相关的操作,并且只有在声明了rollbackForClassName='Exception’之类的配置才会回滚;

spring事务会回滚同一事务中的所有数据库操作,本质上是回滚同一数据库连接上的数据库操作;

spring事务总结:

  • spring事务本质上使用数据库锁;
  • spring事务只有在方法执行过程中出现异常才会回滚,并且只回滚数据库相关的操作;

事务并发异常-丢失更新
如果多个线程操作,基于同一个查询结果对表中的记录进行修改,那么后修改的记录将会覆盖前面修改的记录,前面的修改丢失掉了,这就叫丢失更新。
丢失更新分为两类。第一类丢失更新回滚丢失第二类丢失更新覆盖丢失。SQL92没有定义这种现象,标准定义的所有隔离级别都不允许第一类丢失更新发生。解决丢失更新的办法就是加锁。

悲观锁机制
假定这样的问题是高概率的,最好一开始就锁住,免得更新老出错。

添加共享锁:select * from account lock in share mode;
添加排他锁:select * from account for update;
乐观锁机制
假定这样的问题是小概率的,最后一步做更新的时候再锁住,免得锁住时间太长影响其他人操作。

在表中增加timestamp类型字段,在执行插入或更新时记录最新时间到该字段上;
在修改数据时检查timestamp类型的字段是否改变判断当前的更新基于的查询是否已经过时。
在用户并发数比较少且冲突比较严重的应用系统建议选择悲观锁中的排他锁,其他情况首选乐观锁。
参考地址:
1、理解事务(ACID)——原子性、一致性、隔离性和持久性
2、事务ACID理解
3、spring的事务是什么?与数据库的事务是否一样

理解事务四大特性(Transaction)——原子性、一致性、隔离性和持久性(ACID)相关推荐

  1. 事务四大特征:原子性,一致性,隔离性和持久性(ACID)

    事务四大特征: 原子性,一致性,隔离性和持久性. 1. 原子性(Atomicity) 一个原子事务要么完整执行,要么干脆不执行.这意味着,工作单元中的每项任务都必须正确执行.如果有任一任务执行失败,则 ...

  2. 数据库 事务 四大特性 原子性Atomic 一致性Consistent 隔离性Insulation Isolation 持久性Duration 隔离级别

    https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1/9744607?fr=aladdin 数据库事务 ...

  3. ACDI事务四大特性以及事务的隔离级别

    目录: 一:ACDI事务四大特性 二:事务的隔离级别 Read uncommitted(读未提交) Read committed(读并提交) Repeatable read(重复读) Serializ ...

  4. 事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢失问题...

    事务的4个特性--ACID(原子性.一致性.隔离性和持久性) 事务是一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.事务通常以BEGIN TRANSACTION开始,以COMMI ...

  5. 事务四大特性之——隔离性

    事务四大特性之--隔离性 四大特性 一.4种隔离级别 二.案例 2.1 模拟业务需求 2.2 解决方案 且夫孝始于事亲,中于事君,终于立身. 孝的初始境界是侍奉自己的双亲,中层境界是侍奉自己的国君,最 ...

  6. 事务四大特性及隔离级别

    事务四大特性及隔离级别 咱们都知道事务有四大特性ACID,也就原子性(atomicity|ætəˈmɪsəti|). 一致性(consistency).隔离性(isolation|aɪsəˈleɪʃn ...

  7. 事务概念和事务四大特性和隔离级别

    什么是事务 事务四大特性 原生的JDBC事务处理 事务的隔离级别

  8. mysql数据库事务四大特性的实现原理

    事务的四大特性 原子性.一致性.隔离性.持久性 原子性实现 原子性保证事务要么全执行成功,要么全不执行. mysql使用回滚机制实现,undo log实现回滚. 事务执行 insert.update. ...

  9. 事务四大特性(ACID)

    事务四大特性(ACID) (1)原子性(Atomic) ​ 指事务是一个不可分割的工作单位(像原子一样),事务中的操作要么都发生,要么都不发生.实现事务的原子性,要支持回滚操作,在某个操作失败后,回滚 ...

最新文章

  1. 菜单与工具条的同步 APP_STANDARD.SYNCHRONIZE
  2. 3.Java中的关键字和注释
  3. Mysql水平分表-后端代码
  4. C#中的扩展方法,Linq,IO和多线程的定义和实例
  5. python自动部署环境_在 CentOS 上初始化 Python 环境的自动部署脚本
  6. 通过特性动态获取属性及值
  7. 鸿蒙OS加持!华为MatePad2系列将搭载骁龙888/麒麟9000芯
  8. 基于Keras机器学习库的分类预测
  9. 使用Android OpenGL ES 2.0绘图之四:应用投影和相机视图
  10. Django 模板标签 换行导致异常的处理 linebreaksbr
  11. Atitit 微信小程序的部署流程文档 目录 1.1. 设置https 参照 Atitit tomcat linux 常用命令 1 1.2. 增加证书 腾讯云和阿里云都可申请免费证书,但要一天
  12. iOS13适配暗黑模式/夜间模式/深色模式/暗黑主题(DarkMode)
  13. celery 停止_如何解决django-celery启动后迅速关闭
  14. OpenCV如何进行图像的平滑和锐化处理?
  15. 2022-2028年全球玻璃棉板收入年复合增长率CAGR为 5.0%
  16. 一本通 1335:【例2-4】连通块
  17. 机械CAD软件中还能这样制作材料清单BOM表?
  18. 微商招代理赚钱方法:软文写成小说
  19. 巴比特| 元宇宙每日必读:百度转向海外布局NFT,梦想打造“Web3迪士尼”,胜算几何?...
  20. 全球化(4):CultureInfo

热门文章

  1. 程序员过中秋丨用代码制作一个祝福小网页(html+css)
  2. Pytorch 利用Facenet和Retinaface实现人脸识别
  3. Kubernetes多运营商云服务器部署(kubeadm+ipvs+flannel)
  4. TensorRT cublasStatus == CUBLAS_STATUS_SUCCESS
  5. AMR SLAM ROS入门——前言
  6. CC3200 —— No.1 环境搭建(更新于2020年5月1日)
  7. 浏览器设置跨域及允许携带cookie
  8. 关于css的display:flex inline block inline-block和float
  9. 什么是软件测试?软件测试的目的和流程是什么?——入门软件测试
  10. google play 测试流程梳理及注意事项记录