Spring事务管理机制是Spring提供的一条事务管理的方式,项目中不需要手动去控制事务了。
编程式事务:事务的控制逻辑器(增强逻辑)与业务逻辑混合在一起。
声明式事务:通过配置,在不侵犯原有业务逻辑代码的基础上就添加了事务控制功能。(Spring声明式事务控制就是通过AOP达到这个目的的)
事务基本特性(ACID)
- 原子性(Atomic):一个事务内的所有操作,要么都成功,要么都失败。如:转账,汇款和收款要成功都成功,要失败都失败。
- 一致性(Consistency):指的是数据的一致性,和原子性其实是一件事情,只不过描述的角度不同。原子性是从事务的操作角度,一致性是从数据的角度来描述的。如:转账之前(1000,1000),转账100,那么转账之后的数据状态应该是(900,1100),不应该出现中间状态(900,1000)或者(1000,1100)。
- 隔离性(Isolation):隔离性是当多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
- 持久性(Durability):当事务提交后,它对数据的改变是永久性的。
脏读:脏读是指在一个事务处理过程中读取了另一个未提交的事务中的数据。
如:A的账户有1000元,B要转账给1000元。B启动事务转账1000元,但未提交事务,这时,A查看自己的账户有2000元,认为B转账成功,但是B撤销操作,回滚事务,A的账户还是只有1000元。
不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好有一个事务更新了该数据,两次结果相异,不可被信任。一个事务读取到另一个事务已提交的数据。
如:A的账户有1000元,A查询账户余额并在银行存取1000。在A存钱的过程中,A的老婆网上消费500元,并提交事务。结果A存完钱在查询账户余额只有1500元。
幻读或虚读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。幻读是事务非独立执行时发生的一种现象。
如:A老师查询班级不及格的人数有10人,随后,B老师又重新录入一名不及格的成绩。结果A老师再次查询不及格的人数时,变成11人。
三者之间的差别:
不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一个事务提交的数据。
幻读和不可重复读的区别:两者都是读取了另一个已提交的事务,所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
事务的4种隔离级别:
- read-uncommitted:读未提交,就是一个事务可以读取另一个未提交事务的数据。(最低级别,任何情况都无法保证)
- read-committed:读已提交,就是一个事务要等另一个事务提交后才能读取数据。(可避免脏读)
- repeatable read:就是在开始读取数据(事务开启)时,不再允许修改操作。(可避免脏读,不可重复读的发生)
- Serializable:序列化,是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读,不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。(可避免脏读、不可重复读、幻读的发生)
1)大多数数据库默认的事务隔离级别是Read committed,如Sql server,Oracle。mysql默认的隔离级别是Repeatable read。
2)隔离级别的设置只针对当前链接有效。对于使用mysql命令窗口而言,一个窗口将相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。
3)设置数据库的隔离级别一定要在开启事务之前。