【黄島メインパブリックアカウントトラフィックメインマネタイズサイドビジネスプロジェクト】春の出来事@トランザクション詳細説明

このプロジェクトはすでに1.0で開始されており、全体的な反応は非常に良好です。少し面倒な人は毎日30〜50を稼ぐことができ、上手くいく人は1日50〜100以上を稼ぐことができます。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

このプロジェクトは非常にシンプルです。私たちが行っているのは、トラフィック所有者の広告収入です。1,000程度の読み取りで、他のセルフメディアプラットフォームの広告収入よりもはるかに高い10〜20以上の収入を得ることができます。完全に受動的な収入と言え、記事を投稿するのに毎日30分もかからない!
こんにちは、みなさん、みなさん、今日は春の枠組み問題の原則を説明します。
Springトランザクションには、構成ファイルとアノテーションの2つの方法があります。ここでは、構成ファイルの方法の原則については紹介しません。今回は、アノテーション@Transactionalの原則の説明に焦点を当てます。

1つ:アノテーション@Transactional実装の原則プロセス:
ここに画像の説明を挿入
1。サーバーの起動時にアノテーションスキャンが実行され、@ Transactionalを持つすべてのメソッドがaopプロキシオブジェクトに生成されます
。2。呼び出し元がメソッドを呼び出すと、aopにカットされます。実際のaopのプロキシオブジェクトが呼び出されます。3。jdbc
トランザクションがaopプロキシオブジェクトで開かれ、実際のメソッドが呼び出されます
。4。aopプロキシオブジェクトは、メソッドの実行時にコミットまたはロールバックします。

2:例外がスローされた後、トランザクションのロールバックが失敗するのはなぜですか?
場合によっては、例外が発生してスローされましたが、ロールバックが失敗しました。何が起こっているのでしょうか。この問題を理解するには、Springトランザクションのソースコードを詳細に解釈する必要があります。主要なコアソースコードはorg.springframeworkにあります。 .transaction.interceptor.TransactionAspectSupport、メソッドinvokeWithinTransactionはトランザクションのロジックを制御し、ソースコードは次のとおりです。

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
    
    
        final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        final PlatformTransactionManager tm = this.determineTransactionManager(txAttr);
        final String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
        Object result;
        if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) {
    
    
            final TransactionAspectSupport.ThrowableHolder throwableHolder = new TransactionAspectSupport.ThrowableHolder();

            try {
    
    
                result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, new TransactionCallback<Object>() {
    
    
                    public Object doInTransaction(TransactionStatus status) {
    
    
                        TransactionAspectSupport.TransactionInfo txInfo = TransactionAspectSupport.this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

                        Object var4;
                        try {
    
    
                            Object var3 = invocation.proceedWithInvocation();
                            return var3;
                        } catch (Throwable var8) {
    
    
                            if (txAttr.rollbackOn(var8)) {
    
    
                                if (var8 instanceof RuntimeException) {
    
    
                                    throw (RuntimeException)var8;
                                }

                                throw new TransactionAspectSupport.ThrowableHolderException(var8);
                            }

                            throwableHolder.throwable = var8;
                            var4 = null;
                        } finally {
    
    
                            TransactionAspectSupport.this.cleanupTransactionInfo(txInfo);
                        }

                        return var4;
                    }
                });
                if (throwableHolder.throwable != null) {
    
    
                    throw throwableHolder.throwable;
                } else {
    
    
                    return result;
                }
            } catch (TransactionAspectSupport.ThrowableHolderException var18) {
    
    
                throw var18.getCause();
            } catch (TransactionSystemException var19) {
    
    
                if (throwableHolder.throwable != null) {
    
    
                    this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    var19.initApplicationException(throwableHolder.throwable);
                }

                throw var19;
            } catch (Throwable var20) {
    
    
                if (throwableHolder.throwable != null) {
    
    
                    this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                }

                throw var20;
            }
        } else {
    
    
            TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

            try {
    
    
                //1.执行调用链,循环调用执行前置方法,真实方法
                result = invocation.proceedWithInvocation();
            } catch (Throwable var16) {
    
    
                //1.2出现异常后,进行处理,回滚事务
                this.completeTransactionAfterThrowing(txInfo, var16);
                throw var16;
            } finally {
    
    
                this.cleanupTransactionInfo(txInfo);
            }
            //2.方法执行顺利,调用后置方法,提交事务
            this.commitTransactionAfterReturning(txInfo);
            return result;
        }
    }

コードの最も重要な行についてコメントしました。全体的なロジックは、最初に実際のメソッドのフロントエンドの側面を実行してから、実際のメソッドを実行することです。例外がある場合は、処理され(トランザクションのロールバック)、例外がない場合は、トランザクションが送信され、拡張後のメソッドが実装されます。
したがって、トランザクションのロールバックが失敗する理由を理解するには、メソッドthis.completeTransactionAfterThrowing(txInfo、var16)をさらに詳しく調べる必要があります。ソースコードは次のとおりです。

protected void completeTransactionAfterThrowing(TransactionAspectSupport.TransactionInfo txInfo, Throwable ex) {
    
    
        if (txInfo != null && txInfo.hasTransaction()) {
    
    
            if (this.logger.isTraceEnabled()) {
    
    
                this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "] after exception: " + ex);
            }

            if (txInfo.transactionAttribute.rollbackOn(ex)) {
    
    
                try {
    
    
                    txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
                } catch (TransactionSystemException var7) {
    
    
                    this.logger.error("Application exception overridden by rollback exception", ex);
                    var7.initApplicationException(ex);
                    throw var7;
                } catch (RuntimeException var8) {
    
    
                    this.logger.error("Application exception overridden by rollback exception", ex);
                    throw var8;
                } catch (Error var9) {
    
    
                    this.logger.error("Application exception overridden by rollback error", ex);
                    throw var9;
                }
            } else {
    
    
                try {
    
    
                    txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
                } catch (TransactionSystemException var4) {
    
    
                    this.logger.error("Application exception overridden by commit exception", ex);
                    var4.initApplicationException(ex);
                    throw var4;
                } catch (RuntimeException var5) {
    
    
                    this.logger.error("Application exception overridden by commit exception", ex);
                    throw var5;
                } catch (Error var6) {
    
    
                    this.logger.error("Application exception overridden by commit error", ex);
                    throw var6;
                }
            }
        }

    }

ソースコードから、処理されるのはランタイムRuntimeExceptionおよびその他の例外であることがわかります。このため、Springは、スローされたときに一部の非ランタイム例外を処理しなかったため、ロールバックはありませんでした。
異常な統合関係図は次のとおりです。
ここに画像の説明を挿入
上の図から、IOと同様に、SQL例外が特定の処理を受けない場合、SQL例外はロールバックされないことがわかります。

ソースコードには、トランザクション実行時のトランザクションステータスに基づく詳細コードtxInfo.getTransactionStatus()の行もあります。これが、トランザクションを手動でロールバックするためのコードが次のように記述されている理由です。

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

ソースコードをクリックすると、トランザクションステータスがデフォルトでfalse(コミット済みを意味する)であることがわかります。このメソッドを呼び出すと、true(ロールバック)に変更されます。

public abstract class AbstractTransactionStatus implements TransactionStatus {
    
    
    private boolean rollbackOnly = false;
    private boolean completed = false;
    private Object savepoint;

    public AbstractTransactionStatus() {
    
    
    }

    public void setRollbackOnly() {
    
    
        this.rollbackOnly = true;
    }
    ………………

したがって、要約すると、スプリングトランザクションのロールバックには2つの理由があり
ます。1。スローされた例外は非ランタイム例外RuntimeExceptionです
。2。トランザクションステータスは人為的に変更されます。

では、この問題を解決する方法はありますか?
もちろん、それが人為的なものである場合は、調整または削除する対応するコードを見つけるだけで済みます。
それが動作しない例外である場合、Springもこの問題の解決策を作成しました。2つのオプションがあります
。1。ロールバックを構成します
@ Transactional(rollbackFor = Exception.class)
2。トランザクションを手動でロールバックします。
例外を取得した後、位置コードを呼び出します。TransactionAspectSupport.currentTransactionStatus()。setRollbackOnly();最後に、例外をスローします。

rollbackForは、実行時以外の例外をキャプチャしてロールバックするようにSpringFrameworkに指示します。= Exception.classは、キャプチャするSpringFrameworkのスコープを指示します。したがって、例外をカスタマイズして、ロールバック用に特定の例外のみを取得することもできます。

おすすめ

転載: blog.csdn.net/ncw8080/article/details/113857831