
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
spring框架的学习与应用是目前大多数Java编程开发程序员都需要熟练掌握的一个编程框架,今天我们就通过案例分析来简单了解一下,spring事务特性与应用分析。
一、事务的ACID特性
原子性(Atomicity):一个事务必须被视为一个不可分割的小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。--》主要涉及InnoDB事务。相关特性:事务的提交,回滚,信息表。
一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态。在事务开始前后,数据库的完整性约束没有被破坏。例如违反了性,必须撤销事务,返回初始状态。--》主要涉及内部InnoDB处理,以保护数据不受崩溃,相关特性:双写缓冲、崩溃恢复。
隔离性(isolation):每个读写事务的对象对其他事务的操作对象能相互分离,即:事务提交前对其他事务是不可见的,通常内部加锁实现。--》主要涉及事务,尤其是事务隔离级别,相关特性:隔离级别、innodb锁的底层实现细节。
持久性(durability):一旦事务提交,则其所做的修改会永久保存到数据库。--》涉及到MySQL软件特性与特定硬件配置的相互影响,相关特性:4个配置项:双写缓冲开关、事务提交刷新log的级别、binlog同步频率、表文件;写缓存、操作系统对于fsync()的支持、备份策略等。
二、事务的属性
要保证事务的ACID特性,spring给事务定义了6个属性,对应于声明式事务注解(org.springframework.transaction.annotation.Transactional)@Transactional(key1=*,key2=*...)
事务名称:用户可手动指定事务的名称,当多个事务的时候,可区分使用哪个事务。对应注解中的属性value、transactionManager
隔离级别:为了解决数据库容易出现的问题,分级加锁处理策略。对应注解中的属性isolation
超时时间:定义一个事务执行过程多久算超时,以便超时后回滚。可以防止长期运行的事务占用资源.对应注解中的属性timeout
是否只读:表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务.对应注解中的属性readOnly
传播机制:对事务的传播特性进行定义,共有7种类型。对应注解中的属性propagation
回滚机制:定义遇到异常时回滚策略。对应注解中的属性rollbackFor、noRollbackFor、rollbackForClassName、noRollbackForClassName
其中隔离级别和传播机制比较复杂,咱们细细地品一品。
三、隔离级别
这一块比较复杂,我们从3个角度来看:3种错误现象、mysql的底层技术支持、分级处理策略。这一小节一定要好好看,已经开始涉及核心原理了。
1、.现象(三种问题)
脏读(DrityRead):事务A更新记录但未提交,事务B查询出A未提交记录。
不可重复读(Non-repeatableread):事务A读取一次,此时事务B对数据进行了更新或删除操作,事务A再次查询数据不一致。
幻读(PhantomRead):事务A读取一次,此时事务B插入一条数据事务A再次查询,记录多了。
2、mysql的底层支持(IndoDB事务模型)(一致性非锁定读VS锁定读)
官网飞机票:InnoDBTransactionModel
两种读
在MVCC中,读操作可以分成两类,快照读(Snapshotread)和当前读(currentread)。
快照读:普通的select
当前读:
select*fromtablewhere?lockinsharemode;(加S锁)
select*fromtablewhere?forupdate;(加X锁)
insert,update,delete操作前会先进行一次当前读(加X锁)
其中前两种锁定读,需要用户自己显式使用,后一种是自动添加的。
1.一致性非锁定读(快照读)
一致性非锁定读(consistentnonlockingread)是指InnoDB存储引擎通过多版本控制(multiversionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此等待行上锁的释放。相反的,InnoDB会去读取行的一个快照数据
上面展示了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放。快照数据是指该行之前版本的数据,该实现是通过undo段来完成。而undo用来事务中的回滚数据,因此快照数据本身没有额外的开销,此外,读取快照数据不需要上锁,因为没有事务需要对历史数据进行修改操作。
2.锁定读(当前读)
innoDB对select语句支持两种锁定读:
1)SELECT...FORUPDATE:对读取的行加排它锁(X锁),其他事务不能对已锁定的行再加任何锁。
2)SELECT...LOCKINSHAREMODE:对读取的行加共享锁(S锁),其他事务可以再加S锁,X锁会阻塞等待。
注:这两种锁都必须处于事务中,事务commit,锁释放。所以必须begin或者starttransaction开启一个事务或者索性setautocommit=0把自动提交关掉(mysql默认是1,即执行完sql立即提交)
四、.分级处理策略(四种隔离级别)
官网描述:
InnoDB使用不同的锁定策略支持每个事务隔离级别。对于关键数据的操作(遵从ACID原则),您可以使用强一致性(默认RepeatableRead)。对于不是那么重要的数据操作,可以使用ReadCommitted/ReadUncommitted。Serializable执行比可重读更严格的规则,用于特殊场景:XA事务,并发性和死锁问题的故障排除。
四种隔离级别:
1.ReadUncommitted(读取未提交内容):可能读取其它事务未提交的数据。-脏读问题(脏读+不可重复读+幻读)
2.ReadCommitted(读取提交内容):一个事务只能看见已经提交事务所做的改变。(不可重复读+幻读)
select...from:一致性非锁定读的数据快照(MVCC)是新版本的,但其他事务可能会有新的commit,所以同一select可能返回不同结果。-不可重复读问题
select...fromforupdate:recordlock行级锁.
3.RepeatableRead(可重读):
select…from:同一事务内多次一致性非锁定读,取一次读取时建立的快照版本(MVCC),保证了同一事务内部的可重复读.—狭义的幻读问题得到解决。(Db插入了数据,只不过读不到)
select...fromforupdate(FORUPDATEorLOCKINSHAREMODE),UPDATE,和DELETE:next-keylock下一键锁.
1)对于具有搜索条件的索引,innoDB只锁定找到的索引记录.(next-keylock降为recordlock)
2)对于其他非索引或者非索引,InnoDB会对扫描的索引范围进行锁定,使用next-keylocks,阻塞其他session对间隙的insert操作,-彻底解决广义的幻读问题。(DB没插入数据)
4.Serializable(可串行化):这是高的隔离级别,它是在每个读的数据行上加上共享锁(LOCKINSHAREMODE)。在这个级别,可能导致大量的超时现象和锁竞争,主要用于分布式事务。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。