11

Spring 框架在事务处理方面走了多远?我阅读“Spring In Action”一书及其示例建议您创建不用担心会话和事务管理的 DAO 方法,只需在 XML 中设置会话工厂和事务模板,然后将它们连接到您的 DAO。另一方面,SpringSource.org 的文档表明需要大量的 XML 和/或注释来实现这一点。

这里的真相是什么,我可以按照以下方式编写代码的最简单方法是什么

get session from sessionfactory
open transaction
preform database actions
commit transaction with error handling

让它只是

preform database actions

将我在我的方法中拥有的样板事务代码的数量减少到最低限度?

4

2 回答 2

11

您应该做一些工作才能做到这一点,但根本不是很多。假设您将使用 JPA 并选择您自己的提供程序,例如 Hibernate。然后您需要将定义持久性单元的 persistence.xml 放在 META-INF 文件夹中:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
             version="1.0">
    <persistence-unit name="YourDatabasePersistenceUnitName" transaction-type="RESOURCE_LOCAL"/>           
</persistence>

接下来,在您使用的 Spring 应用程序上下文中定义数据库连接所需的一切,至少应包含以下内容:

<bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>/WEB-INF/jdbc.properties</value>     
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
          destroy-method="close" scope="singleton">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="YourDatabasePersistenceUnitName"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="POSTGRESQL" />
                <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
                <property name="showSql" value="true"/>
                <property name="generateDdl" value="false"/>
            </bean>
        </property>     
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="dataSource" ref="dataSource"/>
    </bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

上面的某些属性可能会根据您的需要进行更改或添加。该示例适用于您可能已经猜到的带有 Hibernate 和 PostgreSQL 数据库的 JPA。

现在您可以像这样简单地定义您的数据访问方法:

@Repository
@Transactional
public class UserJpaDAO {

    protected EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void save(User theUser) {
        entityManager.persist(theUser);
    }

    public User update(User theUser) {
        return entityManager.merge(theUser);
    }
 }

其中 User 是您的应用程序定义的 JPA 实体。您可以在调用您的 DAO 的管理器/控制器层管理事务 - 事实上我就是这样做的 - 但我将它们放在一起,以免使示例过于混乱。

您可能想直接而不是我的示例的很好的参考是 http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html 它引用的前 3 个链接值得去也是。

于 2009-04-16T22:17:26.823 回答
10

Spring 提供了至少 3 种事务划分方式:

1) 程序化处理,通过 TransactionTemplate 或 PlatformTransactionManager - 轻量配置,但具有侵入性

2) 通过 XML 进行声明 - 详细的 XML,但非侵入性

3) 通过注解进行声明——基于 XML,非侵入性

您选择哪一个取决于哪一个最适合您的需求,Spring 不会为您做出这样的选择。从您的问题来看,听起来注释方法就是您所追求的。

我建议阅读 Spring 参考手册,注释驱动的事务处理部分。简洁明了。

我总是先查阅参考文档,只有在文档中没有的书才查阅。

于 2009-04-17T14:41:09.610 回答