1、事務(wù)處理實現(xiàn)
創(chuàng)新互聯(lián)自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站制作、網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元穆棱做網(wǎng)站,已為上家服務(wù),為穆棱各地企業(yè)和個人服務(wù),聯(lián)系電話:18982081108
實現(xiàn)步驟:
* 聲明式事務(wù):
*
* 環(huán)境搭建:
* 1、導(dǎo)入相關(guān)依賴
* 數(shù)據(jù)源、數(shù)據(jù)庫驅(qū)動、Spring-jdbc模塊
* 2、配置數(shù)據(jù)源、JdbcTemplate(Spring提供的簡化數(shù)據(jù)庫操作的工具)操作數(shù)據(jù)
* 3、給方法上標注 @Transactional 表示當前方法是一個事務(wù)方法;
* 4、 @EnableTransactionManagement 開啟基于注解的事務(wù)管理功能;
* @EnableXXX
* 5、配置事務(wù)管理器來控制事務(wù);
* @Bean
* public PlatformTransactionManager transactionManager()
代碼實現(xiàn):
@EnableTransactionManagement @ComponentScan("com.atguigu.tx") @Configuration public class TxConfig { //數(shù)據(jù)源 @Bean public DataSource dataSource() throws Exception{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser("root"); dataSource.setPassword("123456"); dataSource.setDriverClass("com.MySQL.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); return dataSource; } @Bean public JdbcTemplate jdbcTemplate() throws Exception{ //Spring對@Configuration類會特殊處理;給容器中加組件的方法,多次調(diào)用都只是從容器中找組件 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } //注冊事務(wù)管理器在容器中 @Bean public PlatformTransactionManager transactionManager() throws Exception{ return new DataSourceTransactionManager(dataSource()); } }
2、事務(wù)處理原理
原理分析:
* 原理:
* 1)、@EnableTransactionManagement
* 利用TransactionManagementConfigurationSelector給容器中會導(dǎo)入組件
* 導(dǎo)入兩個組件
* AutoProxyRegistrar
* ProxyTransactionManagementConfiguration
* 2)、AutoProxyRegistrar:
* 給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator 組件;
* InfrastructureAdvisorAutoProxyCreator:?
* 利用后置處理器機制在對象創(chuàng)建以后,包裝對象,返回一個代理對象(增強器),代理對象執(zhí)行方法利用攔截器鏈進行調(diào)用;
*
* 3)、ProxyTransactionManagementConfiguration 做了什么?
* 1、給容器中注冊事務(wù)增強器;
* 1)、事務(wù)增強器要用事務(wù)注解的信息,AnnotationTransactionAttributeSource解析事務(wù)注解
* 2)、事務(wù)攔截器:
* TransactionInterceptor;保存了事務(wù)屬性信息,事務(wù)管理器;
* 他是一個 MethodInterceptor;
* 在目標方法執(zhí)行的時候;
* 執(zhí)行攔截器鏈;
* 事務(wù)攔截器:
* 1)、先獲取事務(wù)相關(guān)的屬性
* 2)、再獲取PlatformTransactionManager,如果事先沒有添加指定任何transactionmanger
* 最終會從容器中按照類型獲取一個PlatformTransactionManager;
* 3)、執(zhí)行目標方法
* 如果異常,獲取到事務(wù)管理器,利用事務(wù)管理回滾操作;
* 如果正常,利用事務(wù)管理器,提交事務(wù)
*
*/
核心代碼
1、EnableTransactionManagement注解,注入TransactionManagementConfigurationSelector類
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {
2、TransactionManagementConfigurationSelector類,最終會導(dǎo)入AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class兩個組件。
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { /** * Returns {@link ProxyTransactionManagementConfiguration} or * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY} * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, * respectively. */ @Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: 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); } }
3、AutoProxyRegistrar類的作用為:
給容器中注冊一個 InfrastructureAdvisorAutoProxyCreator 組件;
最終的目的是:利用后置處理器機制在對象創(chuàng)建以后,包裝對象,返回一個代理對象(增強器),代理對象執(zhí)行方法利用攔截器鏈進行調(diào)用;
@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; Set<String> annTypes = importingClassMetadata.getAnnotationTypes(); for (String annType : annTypes) { AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (candidate == null) { continue; } Object mode = candidate.get("mode"); Object proxyTargetClass = candidate.get("proxyTargetClass"); 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; } } } } if (!candidateFound && logger.isInfoEnabled()) { String name = getClass().getSimpleName(); logger.info(String.format("%s was imported but no annotations were found " + "having both 'mode' and 'proxyTargetClass' attributes of type " + "AdviceMode and boolean respectively. This means that auto proxy " + "creator registration and configuration may not have occurred as " + "intended, and components may not be proxied as expected. Check to " + "ensure that %s has been @Import'ed on the same class where these " + "annotations are declared; otherwise remove the import of %s " + "altogether.", name, name, name)); } }
InfrastructureAdvisorAutoProxyCreator類的作用與AnnotationAwareAspectJAutoProxyCreator類的作用類似。
@SuppressWarnings("serial") public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
4、ProxyTransactionManagementConfiguration類
代理事務(wù)管理配置類
@Configuration public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor(); advisor.setTransactionAttributeSource(transactionAttributeSource()); advisor.setAdvice(transactionInterceptor()); if (this.enableTx != null) { advisor.setOrder(this.enableTx.<Integer>getNumber("order")); } return advisor; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) { interceptor.setTransactionManager(this.txManager); } return interceptor; } }
TransactionInterceptor類,事務(wù)調(diào)用:invokeWithinTransaction()方法為最終執(zhí)行的方法
@Override @Nullable public Object invoke(MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); }
TransactionAspectSupport類的最終事務(wù)方法執(zhí)行:
@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. TransactionAttributeSource tas = getTransactionAttributeSource(); final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, 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. retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } else { final ThrowableHolder throwableHolder = new ThrowableHolder(); // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. try { Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> { TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); try { return invocation.proceedWithInvocation(); } 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; } } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
當前題目:Spring事務(wù)處理原理步驟詳解
本文URL:http://chinadenli.net/article6/giciog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站設(shè)計公司、電子商務(wù)、小程序開發(fā)、自適應(yīng)網(wǎng)站、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)