一、總結
1. 動態代理
由cglib或jdk動態代理生成代理類
點擊查看代碼
//代理對象:
//org.springframework.jdbc.datasource.DataSourceTransactionManager
//開啟事務
target.invoke1(){
insertMethod1()
insertMethod2()
updateMethod1()
}
//事務提交
事務操作必須使用同一個connection對象,如何保證
spring每次操作db的時候都需要獲取一個connection連接,每次連接都放在ThreadLocal中。
點擊查看代碼
DataSourceTransactionManager類doGetTransaction
protected Object doGetTransaction() {
DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject();
txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
//這里是到TransactionSynchronizationManager里獲取threadLocal線程綁定的連接
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
2. Transactional原理
點擊查看代碼
1.引入數據源、數據庫驅動、Spring-jdbc模塊
2.事務操作加上@Transactional
3.打開事務功能 @EnableTransactionManagement
4.EnableTransactionManagement引入了一個ImportSelector
5.selector往spring容器中注冊了兩個組件:AutoProxyRegistrar和ProxyTransactionManagementConfiguration
5.1.AutoProxyRegistrar主要利用ImporyBeanDefinitionRegistrar注冊了一個InfrastructureAdvisorAutoProxyCreator組件
InfrastructureAdvisorAutoProxyCreator實現了spring后置處理器接口,讓需要進行事務處理的方法具備事務的能力(即向spring容器中添加了5.2里的BeanFactoryTransactionAttributeSourceAdvisor,進行了增強)
5.2 ProxyTransactionManagementConfiguration向容器中注冊了兩個bean:AnnotationTransactionAttributeSource和TransactionInterceptor放到BeanFactoryTransactionAttributeSourceAdvisor中
5.2.1 AnnotationTransactionAttributeSource 的作用是解析業務代碼中@Transactional注解的元信息,傳播屬性,超時時間,隔離級別
5.2.2 TransactionInterceptor保存了事務屬性信息以及事務管理器;它是一個MethodInterceptor;
6.當業務代碼執行時,由注冊的攔截器TransactionInterceptor進行執行invoke方法
7.TransactionAspectSupport類下的invokeWithinTransaction方法是具體的實現
二、Transactional具體實現原理
1.使用注解@Transactional
點擊查看代碼
//第一步:導入相關數據庫依賴;
//第二步:加事務注解;
@Transactional(rollbackFor = {Exception.class})
public void updateAccount(int id) {
int rows = accounMapper.deduction(id);
if (rows > 0) {
System.out.println("秒殺庫存修改成功");
insertGoodOrder();
} else {
System.out.println("秒殺修改失敗");
}
}
2.開啟事務管理器并注冊事務管理器
點擊查看代碼
@Configuration
@ComponentScan("top.yonyong.db")
//第三步:開啟事務管理功能,讓@Transactional生效
@EnableTransactionManagement
public class DataSourceConfig {
//創建數據源 這個c3p0封裝了JDBC, dataSource 接口的實現
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql//localhost:3306/order");
return dataSource;
}
@Bean //第四步:注冊事務管理器bean
public PlatformTransactionManager platformTransactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
@Bean //第五步:jdbcTemplate能簡化增查改刪的操作
public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
return new JdbcTemplate(dataSource());
}
}
3. 賦予代碼事務能力
點擊查看代碼
package org.springframework.transaction.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Import;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//利用Import給容器添加一個Selector組件;
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
//使用JDK或者是Cglib動態代理
//true:Ciglib動態代理 false JDK動態代理,默認false
boolean proxyTargetClass() default false;
//默認事務增強器是什么模式:代理
AdviceMode mode() default AdviceMode.PROXY;
//最低的優先級
int order() default 2147483647;
}
4. @Import和[@ImportSelector + @ImportBeanDefinitionRegistor ]
spring源碼里常出現這兩個注解:
ImportSelector是一個接口,只需要實現selectImport()方法,返回的是一個數組,即可給容器批量的注冊Bean實例;
ImportBeanDefinitionRegistor也是一個接口,只需要實現registorBeanDefinition()方法就能實現給容器添加bean實例;
點擊查看代碼
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* TransactionManagementConfigurationSelector 實現了AdviceModeImportSelector
* 而AdviceModeImportSelector實現了ImportSelector ,所以也就擁有了向spring容器注冊bean的能力
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
//默認代理模式
//注冊AutoProxyRegistrar和ProxyTransactionManagementConfiguration兩個類
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
private String determineTransactionAspectClass() {
return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}
}
4.1 AutoProxyRegistrar類
通過ImportBeanDefinitionRegistrar給容器中添加組件:InfrastructureAdvisorAutoProxyCreator
點擊查看代碼
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
for (String annoType : annoTypes) {
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {//看它給容器中注冊了什么組件
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
@Nullable //給容器中添加InfrastructureAdvisorAutoProxyCreator組件
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,Object source) {
//這里開始給容器注冊:InfrastructureAdvisorAutoProxyCreator 事務動態代理創建器組件
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
一直點進去發現,InfrastructureAdvisorAutoProxyCreator其實實現了spring后置處理器,用來創建增強的bean
點擊查看代碼
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {}
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable //Bean實例前置增強
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable //Bean實例后置增強
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
4.2 ProxyTransactionManagementConfiguration類
點擊查看代碼
@Configuration(proxyBeanMethods = false)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//開始事務的元數據屬性解析
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
//對屬性元信息的一些增強,比如在注解中設置的一些參數:傳播屬性propagation,回滾的條件rollbackFor等等
//@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
//對我們的事務進行屬性增強;
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
//封裝事務的屬性值,注冊為bean,作為形參供上面的方法使用
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
//新建了這個對象
return new AnnotationTransactionAttributeSource();
}
//主要用于保存事務配置屬性的信息,封裝成一個TransactionInterceptor
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(
TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
點擊查看代碼
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {
public AnnotationTransactionAttributeSource() {
this(true);
}
//花里胡哨不知道干啥的,但最終都會加上一個SpringTransactionAnnotationParser
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
}
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
@Override
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
@Override
@Nullable
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
}
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
//事務傳播屬性的設置
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
//事務的隔離屬性的設置
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
//事務的超時時間設置
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
//事務的回滾條件設置
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
//設置需要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,則進行事務回滾
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
//設置不回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,事務不回滾
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || other instanceof SpringTransactionAnnotationParser);
}
@Override
public int hashCode() {
return SpringTransactionAnnotationParser.class.hashCode();
}
}
到這里:第一就階段的初始化任務就完成了,核心任務:
利用TransactionManagementConfigurationSelector給容器中導入兩個組件:
(1)InfrastructureAdvisorAutoProxyCreator
AutoProxyRegistrar給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator組件,它其實就是一個后置處理器,一個動態代理創建器,利用后置處理器和動態代理對目標方法進行增強,>返回一個增強的實例對象,代理對象執行方法利用攔截器鏈進行調用;
(2)ProxyTransactionManagementConfiguration
對事務管理器的獲取,對事務的元信息進行處理,對目標方法本身的執行,主要是事務能力細節的代理實現,然后給容器中注冊配置生成的事務增強器Bean;
5.調用執行
目標方法的調用,開始調用TransactionInterceptor.invoke() 方法,這個是事務執行的核心
5.1 TransactionInterceptor 類
點擊查看代碼
//這里攔截后封裝成 MethodInterceptor,保存了事務的信息,和aop的邏輯一樣
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
public TransactionInterceptor() {
}
public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
setTransactionManager(ptm);
setTransactionAttributes(attributes);
}
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
//動態代理的調用
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
//這里調用的是TransactionAspectSupport類的方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
//---------------------------------------------------------------------
// Serialization support
//---------------------------------------------------------------------
private void writeObject(ObjectOutputStream oos) throws IOException {
// Rely on default serialization, although this class itself doesn't carry state anyway...
oos.defaultWriteObject();
// Deserialize superclass fields.
oos.writeObject(getTransactionManagerBeanName());
oos.writeObject(getTransactionManager());
oos.writeObject(getTransactionAttributeSource());
oos.writeObject(getBeanFactory());
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
setTransactionManagerBeanName((String) ois.readObject());
setTransactionManager((PlatformTransactionManager) ois.readObject());
setTransactionAttributeSource((TransactionAttributeSource) ois.readObject());
setBeanFactory((BeanFactory) ois.readObject());
}
}
5.2 TransactionAspectSupport類
點擊查看代碼
//TransactionAspectSupport類 invokeWithinTransaction方法
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
//(1):獲取(實踐第二步中)設置的事務屬性信息(propagation = Propagation.REQUIRED, rollbackFor = Exception.class),直接從內存中加載;
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//(2):獲取注冊的事務管理器-PlatformTransactionManager,加載到容器中;
final TransactionManager tm = determineTransactionManager(txAttr);
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method +
". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(
method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//得到事務管理器,關閉事務自動提交;
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//(4): 開始執行目標方法本身doBusiness();
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//(4.1): 如果執行過程中拋出異常則回滾
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//(4.2) 如果執行成功,則提交事務;
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
5.3 初始化datasource時注冊的事務管理器
點擊查看代碼
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
//注入數據源
private DataSource dataSource;
//數據源事務處理器默認構造方法,創建一個數據源事務處理器實例,并設置允許嵌套事務
public DataSourceTransactionManager() {
setNestedTransactionAllowed(true);
}
//根據給定數據源,創建一個數據源事務處理器實例
public DataSourceTransactionManager(DataSource dataSource) {
this();
setDataSource(dataSource);
afterPropertiesSet();
}
//設置數據源
public void setDataSource(DataSource dataSource) {
if (dataSource instanceof TransactionAwareDataSourceProxy) {
//如果數據源是一個事務包裝數據源代理,則獲取事務包裝代理的目標數據源
this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource();
}
else {
this.dataSource = dataSource;
}
}
//獲取數據源
public DataSource getDataSource() {
return this.dataSource;
}
//數據源事務處理器對象構造方法的回調函數
public void afterPropertiesSet() {
if (getDataSource() == null) {
throw new IllegalArgumentException("Property 'dataSource' is required");
}
}
public Object getResourceFactory() {
return getDataSource();
}
//創建事務,對數據庫而言,是由Connection來完成事務工作的。該方法把數據庫的//Connection對象放到一個ConnectionHolder對象中,然后封裝到一個
//DataSourceTransactionObject對象中
protected Object doGetTransaction() {
//創建數據源事務對象
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
//設置數據源事務對象對嵌套事務使用保存點
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//從事務管理容器中獲取存放數據庫Connection的對象
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
//判斷是否已經存在事務
protected boolean isExistingTransaction(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
//根據存放數據庫連接的ConnectionHolder的isTransactionActive屬性來判斷
return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
}
//處理事務開始的方法
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
//如果數據源事務對象的ConnectionHolder為null或者是事務同步的
if (txObject.getConnectionHolder() == null ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
//獲取當前數據源的數據庫連接
Connection newCon = this.dataSource.getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
//為數據源事務對象設置ConnectionHolder
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
//設置數據源事務對象的事務同步 txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
//獲取數據源事務對象的數據庫連接
con = txObject.getConnectionHolder().getConnection();
//根據數據連接和事務屬性,獲取數據庫連接的事務隔離級別
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
//為數據源事務對象設置事務隔離級別
txObject.setPreviousIsolationLevel(previousIsolationLevel);
//如果數據庫連接設置了自動事務提交屬性,則關閉自動提交
if (con.getAutoCommit()) {
//保存數據庫連接設置的自動連接到數據源事務對象中
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
//設置數據庫連接自動事務提交屬性為false,即禁止自動事務提交
con.setAutoCommit(false);
}
//激活當前數據源事務對象的事務配置
txObject.getConnectionHolder().setTransactionActive(true);
//獲取事務配置的超時時長
int timeout = determineTimeout(definition);
//如果事務配置的超時時長不等于事務的默認超時時長
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
//數據源事務對象設置超時時長
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
//把當前數據庫Connection和線程綁定
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
}
}
catch (Exception ex) {
DataSourceUtils.releaseConnection(con, this.dataSource);
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
//事務掛起
protected Object doSuspend(Object transaction) {
//獲取事務對象
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
//將事務對象中的ConnectionHolders設置為null
txObject.setConnectionHolder(null);
ConnectionHolder conHolder = (ConnectionHolder)
//解除事務對象和當前線程的綁定 TransactionSynchronizationManager.unbindResource(this.dataSource);
return conHolder;
}
//事務恢復
protected void doResume(Object transaction, Object suspendedResources) {
//獲取已暫停事務的ConnectionHolder
ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;
//重新將事務對象和當前線程綁定
TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);
}
//事務提交
protected void doCommit(DefaultTransactionStatus status) {
//獲取事務對象
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
//通過事務對象獲取數據庫連接
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
//使用數據庫連接手動進行事務提交
con.commit();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not commit JDBC transaction", ex);
}
}
//事務回滾
protected void doRollback(DefaultTransactionStatus status) {
//獲取事務對象
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
//通過事務對象獲取數據庫連接
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
//通過調用數據庫連接的回滾方法完成事務回滾操作
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
//設置回滾
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +
"] rollback-only");
}
txObject.setRollbackOnly();
}
//操作完成之后清除操作
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
//移除當前線程綁定的ConnectionHolder
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(this.dataSource);
}
Connection con = txObject.getConnectionHolder().getConnection();
try {
//如果事務對象保存了自動事務提交屬性,則設置數據庫連接的自動事務提交屬性
if (txObject.isMustRestoreAutoCommit()) {
con.setAutoCommit(true);
}
//事務結束后重置數據庫連接
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
}
catch (Throwable ex) {
logger.debug("Could not reset JDBC Connection after transaction", ex);
}
//如果事務對象中有新的ConnectionHolder
if (txObject.isNewConnectionHolder()) {
if (logger.isDebugEnabled()) {
logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
}
//釋放數據庫連接
DataSourceUtils.releaseConnection(con, this.dataSource);
}
//清除事務對象的ConnectionHolder
txObject.getConnectionHolder().clear();
}
//數據源事務對象,內部類
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
//是否有新的ConnectionHolder
private boolean newConnectionHolder;
//是否保存自動提交
private boolean mustRestoreAutoCommit;
//設置ConnectionHolder
public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {
//為父類JdbcTransactionObjectSupport設置ConnectionHolder
super.setConnectionHolder(connectionHolder);
this.newConnectionHolder = newConnectionHolder;
}
public boolean isNewConnectionHolder() {
return this.newConnectionHolder;
}
//調用父類JdbcTransactionObjectSupport的相關方法,查詢收費存在事務
public boolean hasTransaction() {
return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive());
}
//設置是否保存自動提交
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
this.mustRestoreAutoCommit = mustRestoreAutoCommit;
}
public boolean isMustRestoreAutoCommit() {
return this.mustRestoreAutoCommit;
}
//設置數據庫連接在操作失敗是,是否只回滾處理
public void setRollbackOnly() {
getConnectionHolder().setRollbackOnly();
}
public boolean isRollbackOnly() {
return getConnectionHolder().isRollbackOnly();
}
}
}
浙公網安備 33010602011771號