星座:处女座
作者:非攻
本文大概
4370
字
读完共需
30
分钟
世界上最有意义的是大概是在学习中寻找快乐吧!
01
事务的属性(ACID)
1)、原子性(Atomicity)
原子性要求事务包含的全部操作是一个不可分割的整体,这些操作要么全部提交成功,要么只要其中一个操作失败,就全部失败。
2)、一致性(Consistency)
一致性要求事务的所包含的操作不能违反数据资源的一致性检查,数据源在事务执行之前处于某个数据一致性状态,那么,事务执行之后也依然需要保持数据间的一致性状态。
3)、隔离性(Isolation)
事务的隔离性主要规定了各个事务之间互相影响的程度。隔离性概念主要面向对数据资源的并发访问(Concurrency),并兼顾影响事务的一致性。
事务指定了4种隔离级别(从弱到强分别是):
①、Read Uncommitted
它是最低的隔离级别。Read Uncommitted最直接的效果是,一个事务可以读取另一个事务没有提交的更新结果。
其无法避免以下问题:脏读(Dirty Read)、不可重复读(Non-Repeatable Read)和幻读(Phanton Read)。
②、Read Committed
通常这是大部分数据库默认的隔离级别。在该隔离级别下,一个事务的更新操作结果只有在该事务提交之后,另一个事务才可能读取到同一笔数据更新后的结果。
可以避免脏读,但无法避免不可重复读和幻读。
③、Repeatable Read
Repeatable Read 可以保证在整个事务的过程中,对同一笔数据的读取结果是相同的,不管其它事务是否同时在对同一笔事务进行更新,也不管其它事务对同一笔数据的更新提交与否。
可以避免脏读和不可重复读,但无法避免幻读。
④、Serializable
它是最严格的级别。所有的事务操作都必须依次顺序执行,可以避免其它级别有的问题。但是太影响系统的并性能。通常,我们会使用其它隔离级别加上相应的并发锁的机制来控制对数据的访问,这样既保证了系统性能不会有太大的损失,也能够在一定程度上保证数据的一致性。
4)持久性(Durability)
一旦整个事务提交成功,对数据所作的变更将被记录并不可逆转。
02
什么是第一类丢失更新、脏读、不可重复读、第二类丢失更新、幻读 ?
①、第一类丢失更新
撤销一个事务的时候,把其它事务已提交的更新数据覆盖了。这是完全没有事务隔离级别造成的。如果事务1被提交,另一个事务被撤销,那么会连同事务1所做的更新也被撤销。
②、脏读(Dirty Read)
如果一个事务对数据进行了更新,但事务还没有提交,另一个事务就可以“看到”该事务没有提交的更新结果。这样就造成的问题就是,如果第一个事务回滚,那么第二个事务在此之前所“看到”的数据就是一笔脏数据。
③、不可重复读取(Non-Repeatable Read)
不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的。所以Read Uncommitted也无法避免不可重复读取的问题。
④、第二类丢失更新
它和不可重复读本质上是同一类并发问题,通常将它看成不可重复读的特例。当两个或多个事务查询相同的记录,然后各自基于查询的结果更新记录时会造成第二类丢失更新问题。每个事务不知道其它事务的存在,最后一个事务对记录所做的更改将覆盖其它事务之前对该记录所做的更改。
⑤、幻读(Phanton Read)
幻读是指同样一个查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下,不管事务2的插入操作是否提交,事务1在插入操作执行之前和之后执行相同的查询,取得的结果集是不同的,所以Read Uncommitted同样无法避免幻读。
无事务隔离级别,则存在:第一类丢失更新、脏读、不可重复读、第二类丢失更新和幻读问题。
Read Uncommitted存在:脏读、不可重复读、第二类丢失更新和幻读问题。
Read committed存在:不可重复读、第二类丢失更新和幻读问题。
Repeatable Read存在:幻读问题。
Serializable 不存在问题。
03
Spring事务的架构?
Spring 的事务框架设计理念的基本原则是:让事务管理的关注点与数据访问关注点相分离。
Spring 的事务抽象包括3个主要接口,分别是PlatformTransactionManager、TransactionDefinition、TransactionSatus。
PlatformTransactionManager负责界定事务边界;TransactionDefinition负责定义事务的相关属性,包括隔离级别、传播行为等;PlatformTransactionManager参照TransactionDefinition的属性定义来开启相关事务。事务开启之后到事务结束期间的事务状态由TransactionStatus负责,我们可以通过TransactionStatus对事务进行有限的控制。
TransactionDefinition常用的实现有DefaultTransactionDefinition和TransactionTemplate(这两个主要用于编程式的事务场景)、DefaultTransactionAttribute和RuleBasedTransactionAttribute(这两个主要使用Spring AOP 进行声明式事务管理的场景中,RuleBasedTransactionAttribute允许我们同时制定多个回滚规则)。
TransactionStatus有一个实现类DefaultTransactionStatus用来记录事务的状态信息。
PlatformTransactionManager的实现类可以分为面向局部事务和面向全局事务两个分支。常用的面向局部事务的PlatformTransactionManager有DataSourceTransactionManager(用于JDBC和Mybatis)和HibernateTransactionManager。
04
Spring的事务管理有两种方式,即编程式事务管理和声明式事务管理。
编程式事务
通过Spring 进行编程式事务管理有两种方式,要么直接使用PlatformTransactionManager,要么使用更方便的TransactionTemplate。
声明式事务
Spring提供了用于声明式事务管理的拦截器TransactionIntercepter(该拦截器用于查询记载着业务方法与对应事务信息之间关系的映射文件(事务驱动的元数据(Metadata))来决定要不要为当前业务方法创建事务)。有了TransactionIntercepter,我们所要做的就是决定使用XML元数据驱动还是使用注解元数据驱动的声明式事务管理。
(1)、XML元数据驱动的声明式事务
可以使用4种配置方式在IoC容器的配置文件中指定事务需要的元数据。
①、使用ProxyFactory(ProxyFactoryBean)+ TransactionIntercepter。
②、使用“一站式”的TransactionProxyFactoryBean。
③、使用BeanNameAutoProxyCreator。
④、使用Spring2.x的声明式事务。
可上下滑动查看
是专门为声明式事务Advice而设置的配置元素,底层当然还是我们的TransactionIntercepter。
添加作者微信
领取专属 10元无门槛券
私享最新 技术干货