Transaktionsmanagement ist erforderlich, um die Datenintegrität und -konsistenz in der Datenbank sicherzustellen. Die AOP-Technik von Spring ermöglicht Entwicklern die Verwaltung der Transaktionsdeklaration.
Hier ein Beispiel, das zeigt, wie die Hibernate-Transaktion mit Spring AOP verwaltet wird.
__P.S Viele Hibernate- und Spring-Konfigurationsdateien sind ausgeblendet, es werden nur einige wichtige Dateien angezeigt. Wenn Sie Hand-On wünschen, laden Sie das vollständige Projekt am Ende des Artikels herunter.
1. Tabellenerstellung
MySQL-Tabellenskripte, eine Produkttabelle und eine Produktmenge .
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. Geschäftsobjekt des Produkts
In dieser ' productBo '-Implementierung fügt die save () -Methode einen Datensatz in die' product '-Tabelle über die Klasse ' productDao ' ein, und einen Mengenbestand in die ' productQoh ' - Tabelle über Klasse " 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");
}
}
Die Bean-Konfigurationsdatei von Spring.
<!-- 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>
Starte es
Product product = new Product();
product.setProductCode("ABC");
product.setProductDesc("This is product ABC");
ProductBo productBo = (ProductBo)appContext.getBean("productBo");
productBo.save(product, 100);
Angenommen, save () verfügt nicht über die Transaktionsfunktion. Wenn eine Ausnahme durch productQohBo.save () ausgelöst wird, werden Sie nur einen Datensatz in die ' product ' - Tabelle einfügen. productQoh ** 'Tabelle. Dies ist ein ernstes Problem und unterbricht die Datenkonsistenz in Ihrer Datenbank.
3. Transaktionsmanagement
Deklarierte eine "** TransactionInterceptor" -Bean und einen "HibernateTransactionManager" für die Hibernate-Transaktion und übergab die erforderliche Eigenschaft.
<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>
Transaktionsattribute
In Transaction Interceptor müssen Sie festlegen, welche Attribute der Transaktion "Ausbreitungsverhalten" verwendet werden sollen. Dies bedeutet, wenn eine transaktionale "ProductBoImpl.save () " -Methode eine andere Methode " productQohBo.save () " heißt, wie soll die Transaktion propagiert werden?
Sollte es innerhalb der bestehenden Transaktion weiterlaufen? oder starten Sie eine neue Transaktion für sich.
Spring unterstützt sieben Ausbreitungsarten:
Eins, wenn keiner existiert.
-
PROPAGATION__SUPPORTS - Unterstützung einer aktuellen Transaktion; ausführen
nicht transaktionsfähig, wenn keine vorhanden ist.
-
PROPAGATION__MANDATORY - Unterstützung einer aktuellen Transaktion; werfen ein
Ausnahme, wenn keine aktuelle Transaktion vorhanden ist.
-
PROPAGATION REQUIRES NEW - Erstellen Sie eine neue Transaktion und setzen Sie die
Aktuelle Transaktion, falls vorhanden.
-
PROPAGATION NOT SUPPORTED - Keine aktuelle Transaktion unterstützen;
vielmehr immer untransaktional ausführen.
-
PROPAGATION__NEVER - Keine aktuelle Transaktion unterstützen; werfen ein
Ausnahme, wenn eine aktuelle Transaktion vorhanden ist.
-
PROPAGATION__NESTED - Wird innerhalb einer geschachtelten Transaktion ausgeführt, wenn a
Aktuelle Transaktion ist vorhanden, verhalten Sie sich wie PROPAGATION__REQUIRED
In den meisten Fällen müssen Sie möglicherweise nur PROPAGATION__REQUIRED verwenden.
Darüber hinaus müssen Sie die Methode definieren, die auch diese Transaktionsattribute unterstützt. Der Methodenname wird im Wildcard-Format unterstützt. Ein save ** entspricht allen Methodennamen, die mit save (…) beginnen.
Transaction Manager
In der Hibernate-Transaktion müssen Sie HibernateTransactionManager verwenden.
Wenn Sie nur mit reiner JDBC arbeiten, verwenden Sie DataSourceTransactionManager ; Verwenden Sie während der JTA JtaTransactionManager .
4. Proxy Factory Bean
Erstellen Sie eine neue Proxy-Factory-Bean für ProductBo und legen Sie die Eigenschaft 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>
Starte es
Product product = new Product();
product.setProductCode("ABC");
product.setProductDesc("This is product ABC");
ProductBo productBo = (ProductBo)appContext.getBean("productBoProxy");
productBo.save(product, 100);
Holen Sie sich Ihre Proxy-Bean ' productBoProxy ' und Ihre save () -Methode unterstützt jetzt Transaktionsfunktionen. Alle Ausnahmen in der productBo.save () -Methode führen dazu, dass die gesamte Transaktion rückgängig gemacht wird. In die Datenbank werden keine Daten eingefügt .
Quellcode herunterladen
Download es - Spring-Hibernate-Transaction-Example.zip