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