[转]Spring事务传播机制和数据库隔离级别
先看下spring的 事务传播行为类型
事务传播行为类型 |
说明 |
PROPAGATION_REQUIRED |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是 |
PROPAGATION_SUPPORTS |
支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY |
使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW |
新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER |
以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 |
当使用 PROPAGATION_NESTED 时, 底层的数据源必须基于 JDBC 3.0 ,并且实现者需要支持保存点事务机制。
readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这 是一个最优化提示 。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具 (如:hibernate或TopLink)时避免dirty checking(试图“刷新”)。
Java代码 /** * 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); } } }
/** * 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); } } }
* <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>
Xml代码 <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>
<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): 两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执 行任何锁操作因此并发事务并没有被隔离开来。
隔离级别 | 更新丢失 | 脏读取 | 重复读取 | 幻读 |
未授权读取 | N | Y | Y | Y |
授权读取 | N | N | Y | Y |
可重复 读取 | N | N | N | Y |
串行 | N | N | N | N |
文章来源:http://blog.csdn.net/willfcareer/article/details/5695530