先看下Spring的事务传播行为类型
事务传播行为类型
|
说明
|
PROPAGATION_REQUIRED
|
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
|
PROPAGATION_SUPPORTS
|
支持当前事务,如果当前没有事务,就以非事务方式执行。
|
PROPAGATION_MANDATORY
|
使用当前的事务,如果当前没有事务,就抛出异常。
|
PROPAGATION_REQUIRES_NEW
|
新建事务,如果当前存在事务,把当前事务挂起。
|
PROPAGATION_NOT_SUPPORTED
|
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
|
PROPAGATION_NEVER
|
以非事务方式执行,如果当前存在事务,则抛出异常。
|
PROPAGATION_NESTED
|
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
|
当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。
readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
Timeout
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。
在xml中的设置应该是 timeout_11 表示超时为11秒。。
为什么呢。。看下面的源码可知。。
/**
* PropertyEditor for TransactionAttribute objects. Takes Strings of form
* <p><code>PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2</code>
* <p>where only propagation code is required. For example:
* <p><code>PROPAGATION_MANDATORY,ISOLATION_DEFAULT</code>
*
* <p>The tokens can be in <strong>any</strong> order. Propagation and isolation codes
* must use the names of the constants in the TransactionDefinition class. Timeout values
* are in seconds. If no timeout is specified, the transaction manager will apply a default
* timeout specific to the particular transaction manager.
*
* <p>A "+" before an exception name substring indicates that
* transactions should commit even if this exception is thrown;
* a "-" that they should roll back.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 24.04.2003
* @see org.springframework.transaction.TransactionDefinition
* @see org.springframework.core.Constants
*/
public class TransactionAttributeEditor extends PropertyEditorSupport {
/**
* Format is PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2.
* Null or the empty string means that the method is non transactional.
* @see java.beans.PropertyEditor#setAsText(java.lang.String)
*/
public void setAsText(String s) throws IllegalArgumentException {
if (s == null || "".equals(s)) {
setValue(null);
}
else {
// tokenize it with ","
String[] tokens = StringUtils.commaDelimitedListToStringArray(s);
RuleBasedTransactionAttribute attr = new RuleBasedTransactionAttribute();
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i].trim();
if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) {
attr.setPropagationBehaviorName(token);
}
else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) {
attr.setIsolationLevelName(token);
}
else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) {
String value = token.substring(DefaultTransactionAttribute.PREFIX_TIMEOUT.length());
attr.setTimeout(Integer.parseInt(value));
}
else if (token.equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) {
attr.setReadOnly(true);
}
else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) {
attr.getRollbackRules().add(new NoRollbackRuleAttribute(token.substring(1)));
}
else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) {
attr.getRollbackRules().add(new RollbackRuleAttribute(token.substring(1)));
}
else {
throw new IllegalArgumentException("Illegal transaction attribute token: [" + token + "]");
}
}
setValue(attr);
}
}
}
从上面可以看出 token.substring() 这个方法把前缀timeout_给去掉了。。所以只剩下11了
从源码可看出来,PREFIX_XXXX 大都是这样写的,但前缀却是写在后面的。。觉得是不是命名有点古怪了,应该是XXXX_PREFIX,害我分析了一段时间。不过在源码上面的解释倒很清楚:
* PropertyEditor for TransactionAttribute objects. Takes Strings of form
* <p><code>PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2</code>
* <p>where only propagation code is required. For example:
* <p><code>PROPAGATION_MANDATORY,ISOLATION_DEFAULT</code>
文笔不好。。就给出个实例,我想一看就该明白了。
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,timeout_11</prop>
</props>
</property>
</bean>
总结先到这里。。等深入研究的时候再把写详细些。。。
事务隔离级别
数据库并发操作存在的异常情况:
1. 更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔离开来。
2. 脏读取(Dirty Reads):一个事务开始读取了某行数据但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险很可能所有操作都被回滚。
3. 不可重复读取(Non-repeatable Reads):一个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交。
4. 两次更新问题(Second lost updates problem):无法重复读取特例,有两个并发事务同时读取同一行数据然后其中一个对它进行修改提交而另一个也进行了修改提交这就会造成第一次写操作失效。
5. 幻读(Phantom Reads):也称为幻像(幻影)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的。
为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。
1.未授权读取(Read Uncommitted):也称未提交读。允许脏读取但不允许更新丢失,如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。
2. 授权读取(Read Committed):也称提交读。允许不可重复读取但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。
3. 可重复读取(Repeatable Read):禁止不可重复读取和脏读取。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。
4. 串行(Serializable):也称可串行读。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。
隔离级别 更新丢失 脏读取 重复读取 幻读
未授权读取 N Y Y Y
授权读取 N N Y Y
可重复读取 N N N Y
串行 N N N N
分享到:
相关推荐
### Spring事务的传播特性和事务隔离级别 #### 一、Spring事务的传播特性(Propagation) 在Spring框架中,事务管理不仅提供了ACID属性的支持,还引入了事务的传播特性,这些特性决定了当一个方法调用另一个方法时,...
Spring 框架提供了一套完善的事务管理机制,其中包含了多种事务传播属性和事务隔离级别。这些特性使得在处理数据库操作时,能够更好地控制事务的边界和行为,从而确保数据的一致性和完整性。 首先,我们来看一下...
### Spring 事务传播特性和事务隔离级别详解 #### 一、Spring 事务传播特性 在进行多层服务架构设计时,事务的管理尤其重要。为了确保数据的一致性,Spring 提供了一种灵活的方式来控制事务的传播行为。下面详细...
### Spring事务的传播特性和隔离级别 #### 一、事务的基本概念 在计算机科学中,事务(transaction)是指一系列操作的集合,这些操作要么全部成功完成,要么全部失败回滚,确保数据的一致性和完整性。事务具备四个...
本DEMO主要探讨的是Spring事务的传播行为和隔离级别,这些概念对于理解和优化数据库操作至关重要。让我们深入理解这些概念及其实际应用。 首先,我们来谈谈事务的传播行为。在Spring中,当一个方法被另一个具有事务...
事务传播特性&事务隔离级别 事务传播特性是指在 Java 中,事务的传播行为,即在多个...事务传播特性和事务隔离级别是 Java 中事务管理的两个重要方面,需要深入了解和正确使用,以确保事务的正确执行和数据的一致性。
总的来说,Spring事务传播原理和数据库事务操作原理是Java开发人员必须掌握的核心知识。理解这些原理,能够帮助我们在开发过程中更好地处理数据一致性问题,保证系统的稳定性和可靠性。通过对Spring事务机制的熟练...
本资料主要探讨的是Spring支持的数据库事务传播属性和事务隔离级别。 一、事务传播属性 1. REQUIRED(默认):如果当前存在事务,则加入该事务;如果没有事务,则创建一个新的事务。这是最常见的事务定义,适用于...
最后,我们提到的是**事务的传播特性**,这是Spring框架中的一种概念,它定义了在一个事务上下文中如何执行另一个方法。例如: - **Not Supported**:不支持事务,如果当前有事务,会挂起事务。 - **Supports**:...
### Spring事务的七大传播行为 ...总结来说,选择合适的事务传播行为和隔离级别对于确保应用程序的数据一致性至关重要。开发者需要根据业务需求权衡性能和数据一致性之间的关系,以选择最合适的设置。
事务的隔离级别和传播行为是理解Spring事务管理的关键概念。以下是对这两个主题的详细解释: 首先,我们来看看Spring支持的五个事务隔离级别: 1. **DEFAULT**:这是PlatformTransactionManager的默认隔离级别,它...
在本课程中,我们将深入探讨Spring事务传播原理和数据库事务操作的基本概念,这对于有Spring开发经验的人员来说,是进一步深化事务控制理解的关键。我们还将触及分布式事务的初步知识,帮助开发者更好地掌握基于...
### Spring 事务隔离和传播机制详解 #### 一、Spring 事务传播机制 Spring 的事务管理功能非常强大,其中一个重要特性就是事务传播行为。事务传播行为定义了当一个方法调用另一个方法时,如何处理事务边界的问题。...
综上所述,理解并熟练掌握Spring的事务管理机制,包括传播特性、隔离级别和readonly属性,对于开发高效、稳定的业务系统至关重要。正确配置和使用这些特性,能有效防止并发控制中的异常情况,保障数据的完整性和一致...
#### 三、数据库隔离级别 为了确保数据的一致性,事务还涉及隔离级别。不同的隔离级别有不同的优缺点,常见的隔离级别包括: 1. **Read-Uncommitted (0)**:最低的隔离级别,允许脏读。 2. **Read-Committed (1)**...
4. **声明式事务管理**:Spring允许在配置文件中声明事务边界,这样可以在多个方法之间定义事务传播行为和隔离级别,而无需在代码中显式处理。 例如,以下是如何使用HibernateTemplate删除Userinfo对象: ```java ...
Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。...通过理解和使用Spring事务流程图,我们可以更好地设计和优化我们的应用程序,确保在多线程环境下的数据一致性。
在配置Spring事务时,可以通过`@Transactional`注解的`isolation`属性来指定隔离级别。 总的来说,理解并合理设置数据库事务的隔离级别是保证系统数据安全、避免并发问题的重要手段。在实际应用中,需要根据业务...
事务传播行为定义了当方法被另一个带有事务属性的方法调用时,该方法如何处理事务。Spring 提供了多种不同的传播行为选项,这些选项可以帮助开发者更好地控制事务的创建与参与。 #### 1. `@Transactional...