本文主要是介绍spring事务处理:调用一个方法前的事务处理过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
实际上,在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 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
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;
}
// 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事务处理:调用一个方法前的事务处理过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!