首先要理解的是spring是如何来标记一个方法是否应该处在事务体之中的。有这样一个接口TransactionDefinition,其中定义了很多常量,它还有一个子接口TransactionAttribute,其中只有一个方法rollback。
TransactionDefinition中有很多常量定义,它们分别属于两种类型,传播途径和隔离级别
Java代码
intPROPAGATION_REQUIRED =0;
int PROPAGATION_REQUIRED = 0;
当然其中也定义了隔离级别
intISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
* A constant indicating that dirty reads are prevented; non-repeatable reads
* and phantom reads can occur. This level only prohibits a transaction
* from reading a row with uncommitted changes in it.
* @see java.sql.Connection#TRANSACTION_READ_COMMITTED
*/
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
同时还有两个对应的方法来得到这样的传播途径和隔离级别
Java代码
intgetPropagationBehavior();
intgetIsolationLevel();
这个接口有一个默认的实现DefaultTransactionDefinition。然后它还有子类,比如说
DefaultTransactionAttribute。Spring在判断一个方法是否需要事务体的时候其实是创建一个TransactionAttribute实现的实例.
有了上面的简单介绍就可以进入真正判断是否需要事务的地方了。这个方法在TransactionAspectSupport类里,
Java代码
protectedTransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
// If the transaction attribute is null, the method is non-transactional.
finalTransactionAttribute sourceAttr =
this.transactionAttributeSource.getTransactionAttribute(method, targetClass);//就是在这里判断了这个方法的事务属性
TransactionAttribute txAttr = sourceAttr;
// If no name specified, apply method identification as transaction name.
if(txAttr !=null&& txAttr.getName() ==null) {
finalString name = methodIdentification(method);
txAttr =newDelegatingTransactionAttribute(sourceAttr) {
publicString getName() {
returnname;
}
};
}
TransactionInfo txInfo =newTransactionInfo(txAttr, method);
//TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性
if(txAttr !=null) {
// We need a transaction for this method
if(logger.isDebugEnabled()) {
logger.debug("Getting transaction for "+ txInfo.joinpointIdentification());
}
// The transaction manager will flag an error if an incompatible tx already exists
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));//这个方法要仔细的看
}
else{
// The TransactionInfo.hasTransaction() method will return
// false. We created it only to preserve the integrity of
// the ThreadLocal stack maintained in this class.
if(logger.isDebugEnabled())
logg