この記事では、Spring トランザクションの詳細な分析 (例を示します) を提供します。必要な方は参考にしていただければ幸いです。
誰もが Spring トランザクション管理を頻繁に使用していると思いますが、それは @Transactional
アノテーションまたは XML
でのトランザクション関連の設定に限定される可能性があります。いずれにせよ、毎日mayで十分です。しかし、プログラマーとしては、面接のためであっても、作成するコードをより適切に制御するためにも、Spring トランザクションの詳細について学ぶ必要があります。
ここで、全員がすぐに答えられるかどうかを確認するために、いくつかの質問を投げかけます。
ネストされた呼び出し にトランザクション メソッドが含まれている場合、Spring ではトランザクション管理、これはどのナレッジ ポイントに属しますか?
私たちが使用するフレームワークは、Hibernate/JPA
または Mybatis
です。最下層には session/ が必要であることは誰もが知っています。接続
オブジェクトは、操作の実行を支援するために使用されます。トランザクションの整合性を確保するには、データベース操作の複数のグループに同じ session/connection オブジェクトを使用する必要があります。また、Spring IOC によって管理されるオブジェクトはすべて
によって管理されることがわかっています。デフォルト。Singleton、これを使用するとスレッド セーフティの問題が発生しないのはなぜですか? Spring は内部的に何をしているのでしょうか?
この記事を読んだクラスメイト
Default誰もが知っている春 ビジネス関連の知識をある程度理解している。 (追記: 特定の記事を知らない場合は、読んでからここに戻ってきてください)Spring トランザクションが Spring AOP のベスト プラクティスの 1 つであることは誰もが知っています。そこで、Spring トランザクションの基本的な知識について話しましょう。 AOP (単純な構成、使用法) を最初に知る必要があります。 AOP についてより包括的に理解したい場合は、「AOP の重要な知識ポイント (用語の紹介、包括的な使用法)」の記事を参照してください。 AOP について話すときは、AOP の基礎となる原理である動的プロキシ設計パターンについて話さなければなりません。この時点で、あなたはすでに AOP の基本を理解しています。したがって、XML/アノテーションを使用して Spring トランザクション管理を構成できます。
IOC の学習では、Spring の Bean のライフ サイクル (BPP オブジェクトにつながる) と、IOC によって管理されるオブジェクトはデフォルトでシングルトンです: シングルトン デザイン パターン (シングルトン オブジェクトがある場合)
State" (メンバー変数付き)、非常に多くのスレッドがこのシングルトン オブジェクトにアクセスすると、スレッドのセキュリティが確保されなくなる可能性があります。では、スレッドセーフとは何でしょうか? 、スレッド セーフを解決するには多くの方法がありますが、そのうちの 1 つは次のとおりです。各スレッドに独自の変数を持たせる: ThreadLocal
上で述べた知識ポイントについてよく知らない場合は、青い「Go in」をクリックして単語を学ぶことをお勧めします。2. 信頼できない直感の 2 つの例
2.1 最初の例
// Service方法 @Transactional public Employee addEmployee() throws Exception { Employee employee = new Employee("3y", 23); employeeRepository.save(employee); // 假设这里出了Exception int i = 1 / 0; return employee; } // Controller调用 @RequestMapping("/add") public Employee addEmployee() { Employee employee = null; try { employee = employeeService.addEmployee(); } catch (Exception e) { e.printStackTrace(); } return employee; }
私の
最初の反応: ロールバックされません。
当時私が考えたのは、サービス層が例外をスローし、それがコントローラーによってキャッチされたためです。ロールバックするかどうかは、コントローラーのキャッチ コード ブロックのロジックによって決定する必要があります。キャッチ コード ブロックがロールバックしない場合は、ロールバックしないでください。
しかし、友人はテスト後にロールバックできると言いました。 (パパパパが顔を平手打ちする)
結論: コンパイル時例外の場合、自動的にロールバックされません。実行時例外の場合は、自動的にロールバックされます2.2 2 番目の例!
2 番目の例は Zhihu@willows の記事から引用したもので、対応する URL は記事の最後に記載されています
ご存知のとおり、@Transactional、今度電話したらどうなるでしょうか?何か用事はあるのでしょうか?アノテーションで囲まれたメソッドは Spring トランザクションで管理できます。その後、
current クラスでトランザクションのないメソッドを使用して、トランザクションのあるメソッドを呼び出すとします
コードで説明します:
// 没有事务的方法去调用有事务的方法 public Employee addEmployee2Controller() throws Exception { return this.addEmployee(); } @Transactional public Employee addEmployee() throws Exception { employeeRepository.deleteAll(); Employee employee = new Employee("3y", 23); // 模拟异常 int i = 1 / 0; return employee; }私の最初の直感は次のとおりです。これは Spring トランザクションの伝播メカニズムに関連しています。 実際、これは Spring トランザクション伝播メカニズムとは何の関係もありません。 以下に説明します。
Spring トランザクション管理は AOP を使用します。 、AOP 動的プロキシの最下層が使用されます。したがって、クラスまたはメソッドにアノテーション @Transactional
をマークすると、次に、写真を使って説明します:
显然地,我们拿到的是代理(Proxy)对象,调用addEmployee2Controller()
方法,而addEmployee2Controller()
方法的逻辑是target.addEmployee()
,调用回原始对象(target)的addEmployee()
。所以这次的调用压根就没有事务存在,更谈不上说Spring事务传播机制了。
Spring トランザクションの詳細な分析 (例付き):
测试结果:压根就Spring トランザクションの詳細な分析 (例付き)
从上面的测试我们可以发现:如果是在本类中没有事务的方法来调用标注注解@Transactional
方法,最后的结论是没有事务的。那如果我将这个标注注解的方法移到别的Service对象上,有没有事务?
@Service public class TestService { @Autowired private EmployeeRepository employeeRepository; @Transactional public Employee addEmployee() throws Exception { employeeRepository.deleteAll(); Employee employee = new Employee("3y", 23); // 模拟异常 int i = 1 / 0; return employee; } } @Service public class EmployeeService { @Autowired private TestService testService; // 没有事务的方法去调用别的类有事务的方法 public Employee addEmployee2Controller() throws Exception { return testService.addEmployee(); } }
测试结果:
因为我们用的是代理对象(Proxy)去调用addEmployee()
方法,那就当然有事务了。
看完这两个例子,有没有觉得3y的直觉是真的水!
如果嵌套调用含有事务的方法,在Spring事务管理中,这属于哪个知识点?
在当前含有事务方法内部调用其他的方法(无论该方法是否含有事务),这就属于Spring事务传播机制的知识点范畴了。
Spring事务基于Spring AOP,Spring AOP底层用的动态代理,动态代理有两种方式:
基于接口代理(JDK代理)
基于接口代理,凡是类的方法非public修饰,或者用了static关键字修饰,那这些方法都不能被Spring AOP增强
基于CGLib代理(子类代理)
基于子类代理,凡是类的方法使用了private、static、final修饰,那这些方法都不能被Spring AOP增强
至于为啥以上的情况不能增强,用你们的脑瓜子想一下就知道了。
值得说明的是:那些不能被Spring AOP增强的方法并不是不能在事务环境下工作了。只要它们被外层的事务方法调用了,由于Spring事务管理的传播级别,内部方法也可以工作在外部方法所启动的事务上下文中。
至于Spring事务传播机制的几个级别,我在这里就不贴出来了。这里只是再次解释“啥情况才是属于Spring事务传播机制的范畴”。
我们使用的框架可能是
Hibernate/JPA
或者是Mybatis
,都知道的底层是需要一个session/connection
对象来帮我们执行操作的。要保证事务的完整性,我们需要多组数据库操作要使用同一个session/connection
对象,而我们又知道Spring IOC所管理的对象默认都是单例的,这为啥我们在使用的时候不会引发线程安全问题呢?内部Spring到底干了什么?
回想一下当年我们学Mybaits的时候,是怎么编写Session工具类?
没错,用的就是ThreadLocal,同样地,Spring也是用的ThreadLocal。
以下内容来源《精通 Spring4.x》
我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态的“状态性对象”采用ThreadLocal封装,让它们也成为线程安全的“状态性对象”,因此,有状态的Bean就能够以singleton的方式在多线程中工作。
我们可以试着点一下进去TransactionSynchronizationManager中看一下:
BBP の完全名は BeanPostProcessor で、一般に オブジェクト ポストプロセッサとして知られています
つまり、オブジェクトを処理できます。 BeanPostProcessor「Processing」を介して。
春の Bean 管理 (または Bean ライフサイクル) も、頻繁にテストされる知識ポイントです。これは、秋の採用で 再整理します。手順は、より重要であるため、ここに投稿します。
##Bean
が設定/実装されている場合##Bean が BeanPostProcessor の before メソッドで構成されている場合は、
または、InstantiationBean を実装し、対応するメソッドを呼び出します。
Bean が BeanPostProcessor の after メソッドで構成されている場合は、
プロキシ オブジェクトを使用する必要があります。では、Spring はどのようにしてそれを行うのでしょうか?
BPP を記述するだけで済みます。postProcessBeforeInitialization メソッドまたは postProcessAfterInitialization メソッドでオブジェクトを判断して、アスペクト ロジックに組み込む必要があるかどうかを確認します。必要な場合は、プロキシを生成します。オブジェクトを取得し、このプロキシ オブジェクトを返すと、最終的にコンテナに注入されるのは当然プロキシ オブジェクトです。Spring は BeanPostProcessor を提供します。これにより、必要なオブジェクトを「
処理」できます。 6. Spring トランザクションのいくつかの重要なインターフェイスを理解する
Spring トランザクションは 2 つのタイプに分類できます:
プログラムによるトランザクションには、次の重要なインターフェイスがあります:
TransactionDefinition: Spring 互換の
トランザクション属性を定義します(トランザクション分離レベル、トランザクションなど)伝播、トランザクション タイムアウト、読み取り専用ステータス)
TransactionStatus: トランザクション の特定の 実行ステータスを表します (トランザクションの実行ステータス情報を取得します。これを使用することもできます)インターフェイス
間接PlatformTransactionManager: トランザクション マネージャー インターフェイス (一連の動作を定義し、特定の実装は別の永続フレームワークに渡されます)完全 ---analogyJDBC)
宣言型トランザクションでは、TransactionStatus インターフェイスと PlatformTransactionManager インターフェイスに加えて、いくつかのインターフェイスがあります。重要なインターフェイス:
TransactionProxyFactoryBean: プロキシ オブジェクトの生成
以上がSpring トランザクションの詳細な分析 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。