1.基本概念
事务,一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
2、特性
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响
下面重点说隔离性
3.隔离性
代码中的事务和数据库中的事务指的是同一件事,数据库的事务默认是自动提交的,可以利用SELECT @@autocommit;
或者SHOW VARIABLES LIKE 'autocommit';
来进行查看
1,代表打开,2代表关闭。利用相关语句将其关闭之后我们,就需要手动提交事务,例如:
然后我们可以设置事务的隔离级别,事务的隔离级别分为四级:未提交读(read uncommitted)、已提交读(read committed)、可重复读(repeatable read)、串行化(serializable)。
未提交读
A事务已执行,但未提交;B事务查询到A事务的更新后数据;A事务回滚;—出现脏数据
已提交读
A事务执行更新;B事务查询;A事务又执行更新;B事务再次查询时,前后两次数据不一致;—不可重复读
幻读
串行化
不允许读写并发操作,写执行时,读必须等待,允许执行读读操作;
如果还是不懂请参考:链接
所以@transactional注解实际上就是在数据库中的事务的开启(begin)----->执行-------->提交(commit)的过程。
关于事务的隔离级别有一个规范化标准,用来规范MYSQL、orcal等数据库,但是mysql已经解决的比该规范更好,如下
规范化标准:
但是MYSQl帮我们在可重复度的情况下帮我们把幻读的情况解决了,所以,MYSQL在可重复读的情况下是不会出现幻读的。
本文的学习视频:添加链接描述
4.有了事务为什么还需要乐观锁和悲观锁
为了减轻数据库压力,放宽事务的锁,把压力放在应用服务器上,也就使用了同步锁;
为什么有了事务这东西,还需要乐观锁悲观锁?事务是粗粒度的概念、乐观锁悲观锁可以更细粒度的控制;
比如抢票,假设余票只有1张;隔离级别可以保证事务A和事务B不能读到对方的数据,也不能更新对方正在更新的数据,但是事务A和事务B都认为还有1张余票,于是出票,并更新为0;
事务解决了并发问题,已经不存在并发问题了;
但是事务B读取的是过时数据,依据过时数据做了业务处理;
所以需要乐观锁或者悲观锁,来记录一个信息:当前已经读取的数据,是不是已经过时了!
事务有这么几种实现方式:锁协议、MVCC、时间戳排序协议、有效性检查协议,锁协议是事务的一种实现方式,事务 = 用锁封装的一个函数,可以重用而已,但是这几个事务的函数覆盖面太粗粒度了,所以有时候我们还得借助于锁来进行细粒度控制;
事务不能保证每个操作结果正确,售票时超卖还是会发生。
事务保证整个操作的成一个组,要么全做要么全不做 但是不能保证多个事务同时读取同一个数据
数据对象被加上排它锁时,其他的事务不能对它读取和修改;加了共享锁的数据对象可以被其他事务读取,但不能修改
事务可以用锁实现,可以保证一致性和隔离性,但是锁用来保证并发性;
隔离性和并发性有点类似,但是隔离性只是保证不会出现相互读取中间数据,却无法解决并发的问题
即使最高隔离级别的序列化,也是允许多个事务同时读取的,所以事务在高并发时依然能产生问题。
感谢博主的梳理https://blog.csdn.net/u013444177/article/details/51760846
关于事务之间的调用,介绍,以及使用注意事项见url