spring事务处理:调用一个方法前的事务处理过程
2014-12-23 14:03
519 查看
实际上,在spring的事务中,只要该类被设置为了事务代理:
拦截器都会创建一个TransactionInfo 对象:
TransactionInfo txInfo = new TransactionInfo(txAttr, method);
而且如果 只要被调用的方法设置了事务属性(txAttr),不管是什么属性都会调用:
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
根据该方法的事务属性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值会有所不同(代码见AbstractPlatformTransactionManager),具体为以下几种情况:
1.当前没有事务时(即以下代码中的((HibernateTransactionObject) transaction).hasTransaction()返回false),会返回以下几种:
1
// Check definition settings for new transaction.
2
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
3
throw new InvalidTimeoutException( " Invalid transaction timeout " , definition.getTimeout());
4
}
5
6
// No existing transaction found -> check propagation behavior to find out how to behave.
7
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
8
throw new IllegalTransactionStateException(
9
" Transaction propagation 'mandatory' but no existing transaction found " );
10
}
11
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
12
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
13
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
14
if (debugEnabled) {
15
logger.debug( " Creating new transaction with name [ " + definition.getName() + " ] " );
16
}
17
doBegin(transaction, definition);
18
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
19
return newTransactionStatus(definition, transaction, true , newSynchronization, debugEnabled, null );
20
}
21
else {
22
// Create "empty" transaction: no actual transaction, but potentially synchronization.
23
boolean newSynchronization = ( this .transactionSynchronization == SYNCHRONIZATION_ALWAYS);
24
return newTransactionStatus(definition, null , false , newSynchronization, debugEnabled, null );
25
}
26
2.当前有事务时
1
private TransactionStatus handleExistingTransaction(
2
TransactionDefinition definition, Object transaction, boolean debugEnabled)
3
throws TransactionException {
4
5
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
6
throw new IllegalTransactionStateException(
7
" Transaction propagation 'never' but existing transaction found " );
8
}
9
10
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
11
if (debugEnabled) {
12
logger.debug( " Suspending current transaction " );
13
}
14
Object suspendedResources = suspend(transaction);
15
boolean newSynchronization = ( this .transactionSynchronization == SYNCHRONIZATION_ALWAYS);
16
return newTransactionStatus(
17
definition, null , false , newSynchronization, debugEnabled, suspendedResources);
18
}
19
20
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
21
if (debugEnabled) {
22
logger.debug( " Suspending current transaction, creating new transaction with name [ " +
23
definition.getName() + " ] " );
24
}
25
Object suspendedResources = suspend(transaction);
26
doBegin(transaction, definition);
27
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
28
return newTransactionStatus(
29
definition, transaction, true , newSynchronization, debugEnabled, suspendedResources);
30
}
31
32
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
33
if ( ! isNestedTransactionAllowed()) {
34
throw new NestedTransactionNotSupportedException(
35
" Transaction manager does not allow nested transactions by default - " +
36
" specify 'nestedTransactionAllowed' property with value 'true' " );
37
}
38
if (debugEnabled) {
39
logger.debug( " Creating nested transaction with name [ " + definition.getName() + " ] " );
40
}
41
if (useSavepointForNestedTransaction()) {
42
// Create savepoint within existing Spring-managed transaction,
43
// through the SavepointManager API implemented by TransactionStatus.
44
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
45
DefaultTransactionStatus status =
46
newTransactionStatus(definition, transaction, false , false , debugEnabled, null );
47
status.createAndHoldSavepoint();
48
return status;
49
}
50
else {
51
// Nested transaction through nested begin and commit/rollback calls.
52
// Usually only for JTA: Spring synchronization might get activated here
53
// in case of a pre-existing JTA transaction.
54
doBegin(transaction, definition);
55
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
56
return newTransactionStatus(definition, transaction, true , newSynchronization, debugEnabled, null );
57
}
58
}
59
最后,txInfo被绑定到当前线程上作为当前事务:
txInfo.bindToThread()
然后,调用实际的目标类的方法并捕捉异常:
try {
// This is an around advice.
// Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
doCloseTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);
return retVal;
}
另外一点,TransactionInfo的newTransactionStatus调用时如果参数的不是null,TransactionInfo.hasTransaction()方法返回true;
拦截器都会创建一个TransactionInfo 对象:
TransactionInfo txInfo = new TransactionInfo(txAttr, method);
而且如果 只要被调用的方法设置了事务属性(txAttr),不管是什么属性都会调用:
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
根据该方法的事务属性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值会有所不同(代码见AbstractPlatformTransactionManager),具体为以下几种情况:
1.当前没有事务时(即以下代码中的((HibernateTransactionObject) transaction).hasTransaction()返回false),会返回以下几种:
1
// Check definition settings for new transaction.
2
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
3
throw new InvalidTimeoutException( " Invalid transaction timeout " , definition.getTimeout());
4
}
5
6
// No existing transaction found -> check propagation behavior to find out how to behave.
7
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
8
throw new IllegalTransactionStateException(
9
" Transaction propagation 'mandatory' but no existing transaction found " );
10
}
11
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
12
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
13
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
14
if (debugEnabled) {
15
logger.debug( " Creating new transaction with name [ " + definition.getName() + " ] " );
16
}
17
doBegin(transaction, definition);
18
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
19
return newTransactionStatus(definition, transaction, true , newSynchronization, debugEnabled, null );
20
}
21
else {
22
// Create "empty" transaction: no actual transaction, but potentially synchronization.
23
boolean newSynchronization = ( this .transactionSynchronization == SYNCHRONIZATION_ALWAYS);
24
return newTransactionStatus(definition, null , false , newSynchronization, debugEnabled, null );
25
}
26
2.当前有事务时
1
private TransactionStatus handleExistingTransaction(
2
TransactionDefinition definition, Object transaction, boolean debugEnabled)
3
throws TransactionException {
4
5
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
6
throw new IllegalTransactionStateException(
7
" Transaction propagation 'never' but existing transaction found " );
8
}
9
10
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
11
if (debugEnabled) {
12
logger.debug( " Suspending current transaction " );
13
}
14
Object suspendedResources = suspend(transaction);
15
boolean newSynchronization = ( this .transactionSynchronization == SYNCHRONIZATION_ALWAYS);
16
return newTransactionStatus(
17
definition, null , false , newSynchronization, debugEnabled, suspendedResources);
18
}
19
20
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
21
if (debugEnabled) {
22
logger.debug( " Suspending current transaction, creating new transaction with name [ " +
23
definition.getName() + " ] " );
24
}
25
Object suspendedResources = suspend(transaction);
26
doBegin(transaction, definition);
27
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
28
return newTransactionStatus(
29
definition, transaction, true , newSynchronization, debugEnabled, suspendedResources);
30
}
31
32
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
33
if ( ! isNestedTransactionAllowed()) {
34
throw new NestedTransactionNotSupportedException(
35
" Transaction manager does not allow nested transactions by default - " +
36
" specify 'nestedTransactionAllowed' property with value 'true' " );
37
}
38
if (debugEnabled) {
39
logger.debug( " Creating nested transaction with name [ " + definition.getName() + " ] " );
40
}
41
if (useSavepointForNestedTransaction()) {
42
// Create savepoint within existing Spring-managed transaction,
43
// through the SavepointManager API implemented by TransactionStatus.
44
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
45
DefaultTransactionStatus status =
46
newTransactionStatus(definition, transaction, false , false , debugEnabled, null );
47
status.createAndHoldSavepoint();
48
return status;
49
}
50
else {
51
// Nested transaction through nested begin and commit/rollback calls.
52
// Usually only for JTA: Spring synchronization might get activated here
53
// in case of a pre-existing JTA transaction.
54
doBegin(transaction, definition);
55
boolean newSynchronization = ( this .transactionSynchronization != SYNCHRONIZATION_NEVER);
56
return newTransactionStatus(definition, transaction, true , newSynchronization, debugEnabled, null );
57
}
58
}
59
最后,txInfo被绑定到当前线程上作为当前事务:
txInfo.bindToThread()
然后,调用实际的目标类的方法并捕捉异常:
try {
// This is an around advice.
// Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
doCloseTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);
return retVal;
}
另外一点,TransactionInfo的newTransactionStatus调用时如果参数的不是null,TransactionInfo.hasTransaction()方法返回true;
相关文章推荐
- spring的事务处理详解:调用一个方法前的事务处理过程(源代码分析)
- spring 事务处理中,同一个类中:A方法(无事务)调B方法(有事务),事务不生效问题
- Spring aop事务代理对象通过TransactionInterceptor处理目标方法事务过程,cglib方式
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
- Spring事务:调用同一个类中的方法
- Java 调用存储过程中传递集合类型处理方法
- 存储过程中 事务的处理 大家有更好的方法请分享 谢谢了。
- Spring AOP代理机制以及方法调用在同一个类的另一个方法的问题
- 在sql2000中,一个存储过程中调用另一个存储过程的实现方法
- 一个用jmail发信的过程,及使用方法.使用时直接调用就行
- SQL Server在存储过程中编写事务处理代码的三种方法
- dotnet中调用存储过程的用法,包含事务处理
- 轮询程序中使用的各种方法:spring调用;http调用;存储过程调用;
- SQL Server在存储过程中编写事务处理代码的三种方法
- Spring的事务管理难点剖析(3):事务方法嵌套调用的迷茫
- 今天写了一个调用存储过程的方法
- 一个ArcGIS Javascript API的BUG和处理办法 - 调用两次Draw工具条deactivate方法导致的错误
- java 数据事务处理 (必须在同一个连接,跨连接此方法无效,得用JPA)
- SQL Server在存储过程中编写事务处理代码的三种方法
- (转) SQL Server在存储过程中编写事务处理代码的三种方法