HibernateでのSpring AOPトランザクション管理
データベースのデータの整合性と一貫性を確保するには、トランザクション管理が必要です。 SpringのAOPテクニックを使用すると、開発者はトランザクション宣言を管理できます。
Spring AOPでHibernateトランザクションを管理する方法を示す例を次に示します。
P.S Many Hibernate and Spring configuration files are hidden, only some important files are shown, if you want hand-on, download the full project at the end of the article.
1. テーブル作成
MySQLテーブルスクリプト、‘product ‘テーブルおよび‘product quantity on hand ‘テーブル。
CREATE TABLE `example`.`product` ( `PRODUCT_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `PRODUCT_CODE` varchar(20) NOT NULL, `PRODUCT_DESC` varchar(255) NOT NULL, PRIMARY KEY (`PRODUCT_ID`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `example`.`product_qoh` ( `QOH_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `PRODUCT_ID` bigint(20) unsigned NOT NULL, `QTY` int(10) unsigned NOT NULL, PRIMARY KEY (`QOH_ID`), KEY `FK_product_qoh_product_id` (`PRODUCT_ID`), CONSTRAINT `FK_product_qoh_product_id` FOREIGN KEY (`PRODUCT_ID`) REFERENCES `product` (`PRODUCT_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2. 製品ビジネスオブジェクト
この 'productBo'実装では、save()メソッドは‘productDao 'クラスを介して'product 'テーブルにレコードを挿入し、'%に手持ちの数量レコードを挿入します(t4)s 'productQohBo'クラスを介したテーブル。
package com.example.product.bo.impl; import com.example.product.bo.ProductBo; import com.example.product.bo.ProductQohBo; import com.example.product.dao.ProductDao; import com.example.product.model.Product; import com.example.product.model.ProductQoh; public class ProductBoImpl implements ProductBo{ ProductDao productDao; ProductQohBo productQohBo; public void setProductDao(ProductDao productDao) { this.productDao = productDao; } public void setProductQohBo(ProductQohBo productQohBo) { this.productQohBo = productQohBo; } //this method need to be transactional public void save(Product product, int qoh){ productDao.save(product); System.out.println("Product Inserted"); ProductQoh productQoh = new ProductQoh(); productQoh.setProductId(product.getProductId()); productQoh.setQty(qoh); productQohBo.save(productQoh); System.out.println("ProductQoh Inserted"); } }
Spring Bean構成ファイル。
それを実行します
Product product = new Product(); product.setProductCode("ABC"); product.setProductDesc("This is product ABC"); ProductBo productBo = (ProductBo)appContext.getBean("productBo"); productBo.save(product, 100);
save()にトランザクション機能がないと仮定すると、productQohBo.save()によって例外がスローされた場合、レコードは 'product'テーブルにのみ挿入され、レコードは '%に挿入されません。 (t3)sのテーブル。 これは深刻な問題であり、データベースのデータの一貫性を損ないます。
3. トランザクション管理
Hibernateトランザクション用に ‘TransactionInterceptor‘ Beanと ‘HibernateTransactionManager‘を宣言し、必要なプロパティを渡します。
PROPAGATION_REQUIRED
トランザクション属性
トランザクションインターセプターでは、どのトランザクションの属性「propagation behavior」を使用するかを定義する必要があります。 つまり、トランザクションの‘ProductBoImpl.save() ‘メソッドが別のメソッド‘productQohBo.save() ‘と呼ばれる場合、トランザクションをどのように伝播する必要がありますか? 既存のトランザクション内で実行を継続する必要がありますか? または、独自の新しいトランザクションを開始します。
Springでサポートされる伝播には7つのタイプがあります。
-
PROPAGATION_REQUIRED –現在のトランザクションをサポートします。存在しない場合は、新しいものを作成します。
-
PROPAGATION_SUPPORTS –現在のトランザクションをサポートします。何も存在しない場合は、非トランザクションで実行します。
-
PROPAGATION_MANDATORY –現在のトランザクションをサポートします。現在のトランザクションが存在しない場合は、例外をスローします。
-
PROPAGATION_REQUIRES_NEW –新しいトランザクションを作成し、現在のトランザクションが存在する場合は一時停止します。
-
PROPAGATION_NOT_SUPPORTED –現在のトランザクションをサポートしていません。むしろ常に非トランザクションで実行します。
-
PROPAGATION_NEVER –現在のトランザクションをサポートしていません。現在のトランザクションが存在する場合は、例外をスローします。
-
PROPAGATION_NESTED –現在のトランザクションが存在する場合はネストされたトランザクション内で実行し、それ以外の場合はPROPAGATION_REQUIREDのように動作します。
ほとんどの場合、PROPAGATION_REQUIREDを使用する必要があるだけです。
さらに、このトランザクション属性もサポートするメソッドを定義する必要があります。 メソッド名はワイルドカード形式でサポートされています。save *はsave(…)で始まるすべてのメソッド名と一致します。
トランザクションマネージャー
Hibernateトランザクションでは、HibernateTransactionManagerを使用する必要があります。 純粋なJDBCのみを扱う場合は、DataSourceTransactionManagerを使用します。 JTA中は、JtaTransactionManagerを使用します。
4. プロキシファクトリBean
ProductBo用の新しいプロキシファクトリBeanを作成し、 ‘interceptorNames‘プロパティを設定します。
transactionInterceptor
それを実行します
Product product = new Product(); product.setProductCode("ABC"); product.setProductDesc("This is product ABC"); ProductBo productBo = (ProductBo)appContext.getBean("productBoProxy"); productBo.save(product, 100);
プロキシBean 'productBoProxy'を取得すると、save()メソッドはトランザクションをサポートするようになります。productBo.save()メソッド内の例外により、トランザクション全体がロールバックされ、データベースにデータが挿入されません。 。