1、当一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题。必须指明希望事务间如何隔离。
2、并发事务所导致的问题可以分为下面3种类型
(1)脏读:对于两个事务T1和T2,T1读取了一个已经被T2更新但是还没有被提交的字段。之后,如果T2回滚,T1读取的内容就是临时且无效的。
(2)不可重复读:对于两个事务T1和T2,T1读取了一个字段,然后T2更新了该字段。之后,T1再次读取同一个字段,值就不一样了。
(3)幻读:对于两个事务T1和T2,T1从一个表中读取某几行,然后T2在该表中插入一些新的行。之后,如果T1再次读取同一个表,就会多出几行。
3、从理论上来说,事务应该彼此完全隔离(如按序列顺序访问),以避免上述的所有问题。然而,这种隔离级别会对性能产生巨大的影响,因为事务必须按顺序运行。在实践中,为了提升性能,事务会以较低的隔离级别运行。
4、事务的隔离级别可以通过隔离事务属性指定。Spring支持5中隔离级别,这些隔离级别是在org.springframework.transaction.TransactionDefinition接口中定义的。
DEFAULT:使用底层数据库的默认隔离级别。对于大多数数据库来说,默认隔离级别都杀死READ_COMMIT。
READ_UNCOMMITED:允许事务读取未被其他事务提交的变更。脏读、不可重复读和幻读问题都可能出现。
READ_COMMITED:只允许事务读取已经被其他事务提交的变更。可以避免脏读问题,但是不可重复读和幻读问题任然可能出现。
REPEATABLE_READ:确保事务可以多次从一个字段中读取相同的值。在这个事务持续期间,禁止其他事务对这个字段进行更新。可以避免脏读和不可重复读问题,但是幻读问题任然可能出现。
SERIALIZABLE:确保事务可以多次从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有并发性问题都可以避免,但是性能十分低下。
Oracle 默认使用的是READ COMMITTED ,MySQL默认事务隔离级别是Repeatable Read
5、
@Transactional(isolation=Isolation.READ_UNCOMMITED)
public void update(...)
@Transactional
public void select(...)
update(...);//更新了,但未提交
Tread.sleep(5000);
select(...)
//update方法又回滚
在上面的代码中,由于update方法的事务隔离级别设置的是READ_UNCOMMITED,所以update为提交的更新,select方法也能读取到,就会出现脏读。
将update方法的隔离级别改为:
@Transactional(isolation=Isolation.READ_COMMITED)
public void update(...)
再次运行代码,select方法必须等待update回滚后才能读取数据库。
为了让底层的数据库可以支持READ_COMMITED隔离级别,它会在已经更新但没有提交的行 上获得更新锁(update lock)。然后其他事务必须等待更新锁被释放后才能读取该行,释放发生在锁定的事务提交或者回滚的时候。
@Transactional(isolation=Isolation.READ_UNCOMMITED)
public void update(...)
@Transactional(isolation=Isolation.READ_UNCOMMITED)
public void select(...)
select(...)//读取了某字段,但未提交
update(...);//更新了,且提交
Tread.sleep(5000);
select(...)//再次读取,值就不一样了
在READ_COMMITED隔离级别中,另一个事务能够更新已经被未提交事务读取过的值 。
@Transactional(isolation=Isolation.REPEATABLE_READ)
public void select(...)
为了让底层的数据库可以支持REPEATABLE_READ隔离级别,它在被读取但还没有被提交的行 上获得读取锁(read lock)。然后其他事务必须等到读取锁被释放后才能更新该行,释放发生在锁定的事务提交或者回滚的时候。
相关推荐
Spring 框架提供了一套完善的事务管理机制,其中包含了多种事务传播属性和事务隔离级别。这些特性使得在处理数据库操作时,能够更好地控制事务的边界和行为,从而确保数据的一致性和完整性。 首先,我们来看一下...
Java 中有七种事务传播特性,分别是: 1. PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启新的事务。 2. PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非...
本文主要关注SSH中的Spring框架在事务管理方面的特性,特别是事务属性。 Spring声明式事务管理是Spring框架的一大亮点,它极大地简化了事务处理的复杂性。在编程时,我们不再需要手动管理数据库连接、关闭连接、...
了解并合理设置事务的传播特性和隔离级别对于构建健壮的事务处理机制至关重要。正确配置可以确保数据的一致性和完整性,同时避免不必要的资源消耗。在实际应用中,开发者应根据业务需求选择合适的事务策略,以平衡...
在Spring中,通过`@Transactional`注解的`isolation`属性可以设置事务隔离级别,如`@Transactional(isolation = Isolation.READ_COMMITTED)`。 理解并合理运用这些事务传播属性和隔离级别,对于编写高效、稳定且...
在深入探讨EJB(Enterprise JavaBeans)的事务属性之前,我们先来理解一下EJB的基本概念及其在企业级应用中的重要性。EJB是Java EE平台的核心组件之一,主要用于构建可扩展、健壮且安全的企业级应用程序。它提供了一...
在 Java Spring 开发框架中,可以通过 `@Transactional` 注解来声明事务管理,其 `isolation` 属性可以设置事务的隔离级别。该属性可接受的参数有: - `Isolation.DEFAULT`:使用数据库自身的默认隔离级别,对于 ...
### Spring 事务传播特性和事务隔离级别详解 #### 一、Spring 事务传播特性 在进行多层服务架构设计时,事务的管理尤其重要。为了确保数据的一致性,Spring 提供了一种灵活的方式来控制事务的传播行为。下面详细...
事务通常包含四个基本属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),合称为ACID特性。 在SQL SERVER和ORACLE中,事务隔离级别是不同的,它们决定了并发操作时...
在配置事务时,我们需要关注事务属性,这些属性定义了事务的行为和特性,包括事务的传播行为、隔离级别、超时值和只读标志。 首先,事务的传播行为是由`getPropagationBehavior()`方法定义的,它指定了当前事务如何...
TransactionDefinition接口是Spring事务管理的核心接口之一,它提供了定义事务特性的方法,包括事务的隔离级别、超时时间、读写模式以及我们关注的事务传播属性。事务传播属性定义了当一个事务方法被另一个事务方法...
Mysql默认的事务隔离级别是可重复读,可以通过设置tx_isolation变量来修改事务隔离级别。 锁机制 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,锁机制是用来解决数据并发访问的一致性和有效性...
Mysql默认的事务隔离级别是可重复读,可以通过设置tx_isolation变量来改变事务隔离级别。 四、锁详解 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,锁机制用于解决数据并发访问的一致性问题...
本知识点将深入探讨Spring中的事务管理,主要包括事务的传播特性、隔离级别以及readonly属性。 1. 事务的传播特性: 在Spring中,事务的传播特性定义了在一个事务方法被另一个事务方法调用时,应该如何处理事务...
事务属性通常由事务的传播行为、事务的隔离级别、事务的超时值和事务只读标志组成。在进行事务划分时,需要进行事务定义,也就是配置事务的属性。 Spring 在 TransactionDefinition 接口中定义这些属性,以供 ...
事务传播行为定义了当方法被另一个带有事务属性的方法调用时,该方法如何处理事务。Spring 提供了多种不同的传播行为选项,这些选项可以帮助开发者更好地控制事务的创建与参与。 #### 1. `@Transactional...
这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了 事务隔离机制、锁机制、MVCC多版本并发控制隔离机制 ,用一整套机制来 解决多事务并发问题。 事务及其ACID属性 事务是由一组...
3. 声明式事务管理:利用Spring AOP的特性,Spring支持声明式事务管理,即可以在配置文件或注解中声明事务属性,这使得事务管理更加灵活和方便。 Spring的事务管理还提供了强大的事务传播行为和隔离级别配置,...
事务属性(`transactionAttributes`)用于定义不同方法的事务传播行为,如`PROPAGATION_REQUIRED`、`PROPAGATION_MANDATORY`等。这种方法的缺点是配置繁琐,需要为每个业务类单独配置。 2. **通过基类配置事务** ...