Springトランザクションの失効の8つの要因

4403 ワード

Springの@Transactional注釈でトランザクションが有効でないシーンを制御しますか?
1、データベースエンジンは取引をサポートしない
ここではMySQLを例にとると、MyISAMエンジンはトランザクション操作をサポートしていないが、InnoDBこそトランザクションをサポートするエンジンであり、一般的にトランザクションをサポートするにはInnoDBを使用する.
MySQLの公式文書によると:
https://dev.mysql.com/doc/refman/5.5/en/storage-engine-setting.html
MySQL 5.5.5からのデフォルトストレージエンジンは:InnoDBで、以前はデフォルトは:MyISAMだったので、この点に注意してください.下位エンジンがトランザクションをサポートしていないのはいくらやっても無駄です.
2スプリングに管理されていない
 
次の例に示します.
// @Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void updateOrder(Order order) {
        // update order
    }

}

この時点で@Service注記を削除すると、このクラスはBeanにロードされず、Springによって管理されず、トランザクションは自然に失効します.
 
3メソッドはpublicではありません
 
Springの公式文書は次のとおりです.
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods. @Transactionalはpublicのメソッドでのみ使用できます.そうしないと、トランザクションは失効しません.非publicメソッドで使用する場合は、AspectJエージェントモードをオンにできます.
 
4
じこよびだしもんだい
 
2つの例を見てみましょう.
@Service
public class OrderServiceImpl implements OrderService {

    public void update(Order order) {
        updateOrder(order);
    }

    @Transactional
    public void updateOrder(Order order) {
        // update order
    }

}

updateメソッドには@Transactional注記が付いていません.@Transactional注記のあるupdateOrderメソッドを呼び出します.updateOrderメソッドのトランザクションは役に立ちますか?
次の例を見てみましょう.
@Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateOrder(Order order) {
        // update order
    }

}

今回updateメソッドに@Transactional、updateOrderにREQUIRES_NEWを追加して新しいトランザクションを開きましたが、新しいトランザクションは役に立ちますか?
この2つの例の答えは:役に立たない!
独自の呼び出しが発生したため、Springのエージェントクラスを経ずにクラス独自のメソッドを呼び出し、デフォルトでは外部でトランザクションを呼び出すだけで有効になります.これも一般的な古典的な問題です.
このソリューションの1つは、クラスに自分を注入し、注入されたオブジェクトで別のメソッドを呼び出すことです.これはあまり優雅ではありません.もう1つの実行可能なソリューションは、Springがどのようにして1つのトランザクションで別のトランザクションを開くかを参考にすることができます.この文章.
 
5データ・ソースにトランザクション・マネージャが設定されていません
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

上記のように、現在のデータ・ソースにトランザクション・マネージャが構成されていない場合は、それも無駄です.
6取引はサポートされていません
次の例を見てみましょう.
@Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void updateOrder(Order order) {
        // update order
    }

}

Propagation.NOT_SUPPORTED:トランザクションで実行しないことを示します.現在、トランザクションが存在する場合は保留中です.詳細は、「トランザクション独立性レベルと伝播メカニズム」という記事を参照してください.
すべて自発的にトランザクション方式で実行することを支持しないで、そのトランザクションが発効してもむだです!
7異常に食べられた
これも多くのシーンがあります.
// @Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {

        }
    }

}

異常を食べて、それから投げ出さないで、事務はどのようにロールバックしましょう!
8異常タイプエラー
上記の例では、もう1つの例外を示します.
// @Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            throw new Exception("    ");
        }
    }

}

デフォルトのロールバックは、RuntimeExceptionです.他の例外のロールバックをトリガーするには、次のような注釈で構成する必要があります.
@Transactional(rollbackFor = Exception.class)

この構成は、Throwable異常クラスおよびそのサブクラスに限定される.
まとめ
本稿では,8つのトランザクションが無効になったシーンをまとめたが,実際に発生したのは,自己呼び出し,異常が食べられる,異常放出タイプが間違っているのの3つである.
冒頭で述べたように、本文は必ずしも完全にまとめられているわけではありません.よくある事務の失効シーンをまとめるだけです.それでも、この8点は面接官を吊るすのに十分です.他のシーンを知っていれば、伝言を共有することを歓迎します.