概要
トランザクション管理はエンタープライズアプリケーションにとって重要であり、異常な状況が発生した場合でもデータの一貫性を確保できます。
Springフレームワークは、次のような特性を備えたトランザクション管理のための一貫した抽象化を提供します。
JTA(JavaトランザクションAPI)、JDBC、Hibernate、JPA(Java Persistence APIおよびJDO(Javaデータオブジェクト)など、さまざまなトランザクションAPIの一貫したプログラミングモデルを提供します。
宣言的トランザクション管理、特に注釈に基づいた宣言的トランザクション管理をサポートします。これは、シンプルで使いやすい
JTAなどの他のトランザクションAPIよりもシンプルなプログラミングトランザクション管理APIを提供します
Spring Dataアクセス抽象化との完全な統合
トランザクション管理方法
Springは、プログラマティックトランザクション管理と宣言的トランザクション管理の2つの方法をサポートしています。
プログラマティックトランザクション管理は、TransactionTemplateを使用するか、基礎となるPlatformTransactionManagerを直接使用します。プログラマティックトランザクション管理の場合、SpringはTransactionTemplateの使用をお勧めします。
宣言的なトランザクション管理はAOP上に構築されています。その本質は、メソッドを前後にインターセプトし、ターゲットメソッドが始まる前にトランザクションを作成または追加することです。ターゲットメソッドを実行した後、トランザクションは実行状況に応じて送信またはロールバックされます。宣言的トランザクションの最大の利点は、プログラムでトランザクションを管理する必要がないことです。したがって、ビジネスロジックコードでドーパントトランザクション管理コードをドーパントする必要はありません。 Configurationファイルに関連するトランザクションルール宣言を(または@Transactional Annotationを介して)作成するだけで、ビジネスロジックにトランザクションルールを適用できます。
明らかに、宣言的なトランザクション管理は、春までに提唱されている非侵襲的開発方法であるプログラマティックトランザクション管理よりも優れています。宣言的なトランザクション管理により、ビジネスコードは汚染がありません。通常のPOJOオブジェクトは、注釈を追加することにより、完全なトランザクションサポートを取得できます。プログラミングトランザクションと比較して、宣言的トランザクションの唯一の欠点は、後者の最高の粒度がメソッドレベルでのみ機能し、プログラマティックトランザクションがコードブロックレベルで行動できるため、達成できないことです。ただし、そのような要件があっても、トランザクション管理を必要とするコードブロックなど、多くの回避策があります。
また、宣言的なトランザクション管理に一般的に使用される2つの方法もあります。 1つはTXとAOPの名前空間に基づいたXML構成ファイルで、もう1つは@TransactionAl Annotationに基づいています。明らかに、注釈ベースの方法はよりシンプルで使いやすく、より爽やかです。
自動コミット(オートコンミット)および接続が閉じたときに自動的に送信するかどうか
自動提出
デフォルトでは、データベースは自動送信モードです。各ステートメントは別のトランザクションにあります。このステートメントの実行が完了すると、実行が成功した場合、トランザクションは暗黙的に提出されます。
実行が失敗した場合、トランザクションは暗黙的にロールバックされます。
通常のトランザクション管理の場合、関連する操作のセットがトランザクションにあるため、データベースの自動コミットモードをオフにする必要があります。ただし、これについて心配する必要はありません。Springは、Falseへの基礎となる接続の自動コミット機能を設定します。
org/springframework/jdbc/datasource/datasourcetransactionmanager.java
//必要に応じて手動コミットに切り替えます。これは一部のJDBCドライバーで非常に高価です//したがって、不必要にそれを行いたくありません(たとえば、既にそれを設定するように接続プールを設定した場合)。if(con.getautocommit()){txobject.setmustrestoreautocommit(true); if(logger.isdebugenabled()){logger.debug( "jdbc connection [" + con + "]マニュアルコミット"にjdbc接続[" + con +"]); } con.setautocommit(false);}一部のデータ接続プールは、自動トランザクションコミットをオフにする設定を提供します。これは、接続プールをセットアップするときにオフにするのが最善です。ただし、C3P0はこの機能を提供せず、Springにのみ依存して設定できます。
JDBC仕様は、接続オブジェクトが確立されると、DBMS全体のデフォルト値である自動コミットモードである必要があり、必要に応じて自動コミットを明示的にオフにする必要があることを規定しているためです。 C3P0はこの仕様を順守し、クライアントコードが必要な提出モードを明示的に設定できるようにします。
接続が閉じたときに自動的に送信するかどうか
接続が閉じられたら、コミットされていないトランザクションがある場合は何を処理する必要がありますか? JDBC仕様では、C3P0のデフォルトポリシーが、コミットされていないトランザクションをロールバックすることであることは言及されていません。これは正しい戦略ですが、この問題に関するJDBCドライバープロバイダーの間では合意はありません。
C3P0のAutoCommitOnCloseプロパティはデフォルトでfalseであるため、移動しない必要はありません。または、このプロパティを明示的にFalseに設定することもできます。これはより明確になります。
注釈ベースの宣言トランザクション管理構成
spring-servlet.xml
<! - トランザクションサポート - > <! - PlatformTransactionMnager-> <Bean Id = "Txmanager"> <プロパティ名= "DataSource" Ref = "DataSource" />> < /bean> <! - トランザクションアノテーションサポート - > <TX:Annotation-Driven Transaction-Manager = "Txmanager" />>>>>
また、spring-servlet.xmlにTxネームスペースを追加します
... xmlns:tx = "http://www.springframework.org/schema/tx" xmlns:aop = "http://www.springframework.org/schema/aop" xsi:schemalocation = " http://www.springframework.org/schema/tx/spring-tx.xsd ...
MyBatisは、追加の構成なしでSpring Transaction Managementに自動的に参加します。 org.mybatis.spring.sqlsessionfactorybeanが参照するデータソースがDataSourcetransactionManagerが参照されるデータソースと一致している限り、トランザクション管理は機能しません。
さらに、依存関係パッケージaopalliance.jarをダウンロードして、Web-inf/libディレクトリに配置する必要があります。それ以外の場合は、春が初期化されたときに例外が報告されます
java.lang.noclassdeffounderror:org/aopalliance/intercept/methodinterceptor
春のトランザクション機能
春のすべてのトランザクション管理ポリシークラスは、org.springframework.transaction.platformtransactionmanagerインターフェイスから継承されます。
Public Interface PlatformTransactionManager {transactionStatus getTransaction(transactionDefinition ridention)Throws TransactionException; void commit(transactionStatusステータス)TransactionExceptionをスローします。 void lollback(transactionStatusステータス)transactionexception;}TransactionDefinitionインターフェイスは、次の特性を定義します。
トランザクション分離レベル
分離レベルは、いくつかの同時トランザクション間の分離の程度を指します。隔離レベルを表す5つの定数は、TransactionDefinitionインターフェイスで定義されています。
TransactionDefinition.Isolation_Default:これはデフォルト値であり、基礎となるデータベースに使用されるデフォルトの分離レベルを示します。ほとんどのデータベースの場合、この値は通常transactionDefinition.isolation_read_committeです。
TransactionDefinition.Isolation_Read_unCommitted:この分離レベルは、あるトランザクションが別のトランザクションによって変更されたデータを読み取ることができるが、まだコミットされていないことを示しています。このレベルでは、汚い読み物、反復的な読み取り、幻想の読み取りを妨げないため、この分離レベルはめったに使用されません。たとえば、PostgreSQLには実際にはこのレベルがありません。
TransactionDefinition.Isolation_Read_Committed:この分離レベルは、あるトランザクションが別のトランザクションによってコミットされたデータのみを読み取ることができることを意味します。このレベルは汚い読み取りを防ぎます。これは、ほとんどの場合、推奨値でもあります。
TransactionDefinition.Isolation_Repeatable_Read:この分離レベルは、トランザクションがプロセス全体でクエリを複数回実行できることを示し、返されるレコードは毎回同じです。このレベルは、汚れた繰り返しのない測定値を防ぎます。
TransactionDefinition.Isolation_Serializable:すべてのトランザクションは順番に1つずつ実行されるため、トランザクション間に干渉の可能性がありません。つまり、このレベルは汚い読み、非繰り返し読み取り、幻の読み取りを防ぐことができます。しかし、これはプログラムのパフォーマンスに深刻な影響を与えます。このレベルは通常使用されません。
トランザクション通信動作
いわゆるトランザクション伝播動作は、現在のトランザクションが開始される前にトランザクションコンテキストがすでに存在する場合、トランザクションメソッドの実行動作を指定できるいくつかのオプションがあることを指します。 TransactionDefinitionの定義には、伝播挙動を表す次の定数が含まれます。
TransactionDefinition.Propagation_Required:トランザクションが現在存在する場合は、トランザクションに参加します。現在トランザクションがない場合は、新しいトランザクションを作成します。これがデフォルト値です。
TransactionDefinition.Propagation_Requires_New:新しいトランザクションが作成され、トランザクションが現在存在する場合、現在のトランザクションは停止されます。
TransactionDefinition.Propagation_Supports:現在トランザクションがある場合は、トランザクションに参加します。現在トランザクションがない場合、それは非貿易の方法で実行され続けています。
TransactionDefinition.Propagation_Not_Supported:非貿易方法で実行され、トランザクションが現在存在する場合、現在のトランザクションは停止されます。
TransactionDefinition.Propagation_never:非貿易方法で実行され、トランザクションが現在存在する場合は例外をスローします。
TransactionDefinition.Propagation_Mandatory:現在トランザクションがある場合は、トランザクションに参加します。現在トランザクションがない場合、例外がスローされます。
TransactionDefinition.Propagation_Nested:トランザクションが現在存在する場合、トランザクションが作成され、現在のトランザクションのネストされたトランザクションとして実行されます。トランザクションがない場合、値はtransactionDefinition.propagation_requiredに相当します。
トランザクションタイムアウト
いわゆるトランザクションタイムアウトとは、トランザクションによって許可される最大時間を指します。制限時間を超えているが、トランザクションが完了していない場合、トランザクションは自動的にロールバックされます。 TransactionDefinitionでは、タイムアウトはintの値で表され、そのユニットは秒です。
デフォルト設定は、基礎となるトランザクションシステムのタイムアウト値です。基礎となるデータベーストランザクションシステムがタイムアウト値を設定しない場合、それはなしであり、タイムアウト制限はありません。
トランザクション読み取り専用属性
読み取り専用のトランザクションは、クライアントコードが読み取り専用であるがデータを変更しない状況で使用されます。読み取り専用のトランザクションは、Hibernateを使用する場合など、特定のシナリオで最適化に使用されます。
デフォルトは読み取りおよび書き込みトランザクションです。
スプリングトランザクションロールバックルール
Spring Transaction Managerにトランザクションをロールバックするように指示する推奨される方法は、現在のトランザクションのコンテキスト内で例外をスローすることです。 Spring Transaction Managerは、未処理の例外をキャッチし、ルールに基づいて例外をスローするトランザクションをロールバックするかどうかを決定します。
デフォルトでは、スプリングがスローされた例外がチェックされていない例外である場合にのみトランザクションをロールバックします。つまり、スローされた例外はruntimeexceptionのサブクラスです(エラーもトランザクションロールバックを引き起こします)。
チェックされた例外を含め、それらの例外がスローされたときにロールバックするようにトランザクションを明示的に構成することができます。また、例外がスローされたときにロールバックしないトランザクションを明確に定義することも可能です。
また、SetRollBackonly()メソッドをプログラム的に使用して、トランザクションをロールバックする必要があることを示すこともできます。 setrollbackonly()を呼び出した後にできる唯一のことはロールバックです。
@transactional annotation
@transactionalプロパティ
| 財産 | タイプ | 説明する |
|---|---|---|
| 価値 | 弦 | オプションの予選記述子。使用するトランザクションマネージャーを指定します |
| 伝搬 | 列挙:伝播 | オプションのトランザクション伝播動作設定 |
| 分離 | 列挙:分離 | オプションのトランザクション分離レベル設定 |
| 読みます | ブール | 読み取りと書き込みまたは読み取り専用のトランザクション、デフォルトの読み取りと書き込み |
| タイムアウト | int(秒単位で) | トランザクションタイムアウト設定 |
| Rollbackfor | クラスオブジェクトアレイは、スロー可能から継承する必要があります | トランザクションロールバックを引き起こす例外クラスの配列 |
| RollbackforClassName | クラス名の配列は、スロー可能から継承する必要があります | トランザクションロールバックを引き起こす例外クラス名の配列 |
| Norollbackfor | クラスオブジェクトアレイは、スロー可能から継承する必要があります | トランザクションロールバックを引き起こさない例外クラスアレイ |
| norollbackforclassname | クラス名の配列は、スロー可能から継承する必要があります | トランザクションロールバックを引き起こさない例外クラス名の配列 |
使用法
@Transactionalは、インターフェイス、インターフェイスメソッド、クラス、クラスメソッドで動作することができます。クラスで行動する場合、クラスのすべてのパブリックメソッドには、そのタイプのトランザクションプロパティがあります。同時に、メソッドレベルでこの注釈を使用して、クラスレベルの定義をオーバーライドすることもできます。
@Transactionalアノテーションはインターフェイス、インターフェイスメソッド、クラス、およびクラスメソッドに適用できますが、Springは、インターフェイスまたはインターフェイスメソッドでこの注釈を使用しないことをお勧めします。これは、インターフェイスベースのプロキシを使用する場合にのみ有効になるためです。さらに、 @transactionalアノテーションは、スプリングAOPの性質によって決定されるパブリックメソッドにのみ適用する必要があります。保護された、プライベート、またはデフォルトの可視性方法で@Transactionalアノテーションを使用する場合、これは無視され、例外はスローされません。
デフォルトでは、AOPプロキシによって外部からのメソッド呼び出しのみがキャプチャされます。つまり、 @Transactional Annotationを使用して呼び出されたメソッドが変更された場合でも、クラス内のこのクラス内の他のメソッドを呼び出すことはトランザクション動作を引き起こしません。
@transactional(readonly = true)public class defaultfooserviceはfooservice {public foo getfoo(string fooname){//何かをする} updatefoo(foo foo){//何かをする}}要約します
上記は、春の@transactionalアノテーションの使用に関するこの記事の解釈のすべての内容であり、私はそれがすべての人に役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!