データベースにおけるデータの整合性と整合性を保証するには、トランザクション管理が必要です。 SpringのAOP技術は、開発者がトランザクションの宣言を管理できるようにします。

Spring AOPでHibernateトランザクションを管理する方法を示す例です。

__P.S多くのHibernateとSpringの設定ファイルは非表示になっています。重要なファイルがいくつか表示されますが、手作りしたい場合は記事の最後に完全なプロジェクトをダウンロードしてください。

1.テーブルの作成

MySQLテーブルスクリプト、

‘製品

‘テーブル、 ‘

手元にある製品

‘の表を参照してください。

CREATE TABLE  `mkyong`.`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  `mkyong`.`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

‘テーブルにレコードを挿入し、 ‘

productQoh



productQohBo

‘クラスです。

package com.mkyong.product.bo.impl;

import com.mkyong.product.bo.ProductBo;
import com.mkyong.product.bo.ProductQohBo;
import com.mkyong.product.dao.ProductDao;
import com.mkyong.product.model.Product;
import com.mkyong.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 business object -->
   <bean id="productBo" class="com.mkyong.product.bo.impl.ProductBoImpl" >
    <property name="productDao" ref="productDao"/>
    <property name="productQohBo" ref="productQohBo"/>
   </bean>

   <!-- Product Data Access Object -->
   <bean id="productDao" class="com.mkyong.product.dao.impl.ProductDaoImpl" >
    <property name="sessionFactory" ref="sessionFactory"></property>
   </bean>

それを実行します

    Product product = new Product();
    product.setProductCode("ABC");
    product.setProductDesc("This is product ABC");

    ProductBo productBo = (ProductBo)appContext.getBean("productBo");
    productBo.save(product, 100);

3.トランザクション管理

Hibernateトランザクションのために ‘

TransactionInterceptor

‘ beanと ‘

HibernateTransactionManager

‘を宣言し、必要なプロパティを渡します。

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="transactionInterceptor"
       class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
       <props>
        <prop key="save">PROPAGATION__REQUIRED</prop>
       </props>
    </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="dataSource" ref="dataSource"/>
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

</beans>

トランザクション属性

トランザクションインターセプタでは、どのトランザクションの属性 ‘

伝播動作

‘を使用するべきかを定義する必要があります。つまり、トランザクション

‘ProductBoImpl.save()

‘メソッドが ‘

productQohBo.save()

‘という別のメソッドと呼ばれ、トランザクションがどのように伝播されるべきかを意味します。

既存のトランザクション内で引き続き実行する必要がありますか?または独自のトランザクションを開始することができます。

Springでサポートされる伝播には7つのタイプがあります。


  • PROPAGATION__REQUIRED

    – 現在のトランザクションをサポートします。新しいを作成します

存在しなければ1つです。


  • PROPAGATION__SUPPORTS

    – 現在のトランザクションをサポートします。実行する

存在しなければ非トランザクション的に。


  • PROPAGATION__MANDATORY

    – 現在のトランザクションをサポートします。投げる

現在のトランザクションが存在しない場合は例外です。


  • PROPAGATION

    REQUIRES

    NEW

    – 新しいトランザクションを作成し、

現在のトランザクションが存在する場合はそれを返します。


  • PROPAGATION

    NOT

    SUPPORTED

    – 現在のトランザクションをサポートしません。

むしろ常に非トランザクション的に実行されます。


  • PROPAGATION__NEVER

    – 現在のトランザクションをサポートしません。投げる

現在のトランザクションが存在する場合は例外です。


  • PROPAGATION__NESTED

    – もしネストされたトランザクション内で実行すると、

現在のトランザクションが存在する場合は、PROPAGATION__REQUIRED elseのように動作します。

ほとんどの場合、PROPAGATION__REQUIREDを使用するだけで済みます。

さらに、このトランザクション属性をサポートするメソッドも定義する必要があります。メソッド名は、ワイルドカード形式でサポートされています。

save

** は、save(…​)で始まるすべてのメソッド名に一致します。

トランザクションマネージャ

Hibernateトランザクションでは、

HibernateTransactionManager

を使用する必要があります。

純粋なJDBCのみを扱う場合は、

DataSourceTransactionManager

を使用してください。 JTAは

JtaTransactionManager

を使います。

4.プロキシファクトリBean

  • ProductBo

    の新しいプロキシファクトリBeanを作成し、 ‘

    interceptorNames ** ‘プロパティを設定します。

   <!-- Product business object -->
   <bean id="productBo" class="com.mkyong.product.bo.impl.ProductBoImpl" >
    <property name="productDao" ref="productDao"/>
    <property name="productQohBo" ref="productQohBo"/>
   </bean>

   <!-- Product Data Access Object -->
   <bean id="productDao" class="com.mkyong.product.dao.impl.ProductDaoImpl" >
    <property name="sessionFactory" ref="sessionFactory"></property>
   </bean>

   <bean id="productBoProxy"
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="productBo"/>
    <property name="interceptorNames">
        <list>
            <value>transactionInterceptor</value>
        </list>
    </property>
  </bean>

それを実行します

    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()

メソッド内の例外によってトランザクション全体がロールバックされ、データはデータベースに挿入されません。

ソースコードをダウンロードする

それをダウンロードする –

Spring-Hibernate-Transaction-Example.zip