How far does the spring framework go with transaction handling? My reading of the book "Spring In Action" suggestions with its examples that you create DAO methods that don't worry about Session and Transaction management fairly simply by setting up a session factory and transaction template in XML and then wiring them into your DAO. SpringSource.org's documentation, on the other hand, suggests that need tons of XML and/or annotation to make this happen.
Spring框架与事务处理有多远?我阅读了“Spring In Action”一书的建议,其中的例子是您创建了DAO方法,不必担心会话和事务管理,只需在XML中设置会话工厂和事务模板,然后将它们连接到DAO中。另一方面,SpringSource.org的文档表明需要大量的XML和/或注释来实现这一点。
What is the truth here, what is the simplest way I can take code along the lines of
这里的真相是什么,我可以采用最简单的方式采用代码
get session from sessionfactory
open transaction
preform database actions
commit transaction with error handling
and make it just
并使它成为公正
preform database actions
reducing the amount of boiler plate transactional code that I have across my methods to a minimum?
将我的方法中的锅炉板交易代码量减少到最少?
2 个解决方案
#1
10
Spring provides at least 3 ways of transaction demarcation:
Spring提供至少3种事务划分方式:
1) Programmatic handling, via TransactionTemplate or PlatformTransactionManager - light on config, but invasive
1)通过TransactionTemplate或PlatformTransactionManager进行编程处理 - 点亮配置,但是入侵
2) Declarative via XML - verbose XML, but non-invasive
2)通过XML声明 - 详细XML,但非侵入性
3) Declarative via annotations - light on XML, not invasive
3)通过注释声明 - 点亮XML,而不是侵入性
Which one you pick depends on which one best suits your needs, Spring doesn't make that choice for you. From your question, it sounds like the annotation approach is what you're after.
您选择哪一个取决于哪一个最适合您的需求,Spring不会为您做出选择。从您的问题来看,听起来就像注释方法就是您所追求的。
I suggest reading the Spring reference manual, the section of annotation-driven transaction handling. It's clear and concise.
我建议阅读Spring参考手册,注释驱动的事务处理部分。它简洁明了。
I always consult the ref docs first, and only consult a book if it's not in the docs.
我总是先咨询参考文档,如果它不在文档中,则只查阅一本书。
#2
11
There is some work you are supposed to do to be able to do just that but it's not much at all. Supposedly, you will use JPA with pick your own provider, e.g. Hibernate. Then you need to place persistence.xml that defines the persistence unit in the META-INF folder:
你应该做一些工作才能做到这一点,但它根本不是很多。据推测,您将使用JPA选择您自己的提供商,例如休眠。然后,您需要在META-INF文件夹中放置定义持久性单元的persistence.xml:
<?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>
Next, define everything necessary for database connection in the Spring application context you use, at minimum it should contain these:
接下来,在您使用的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"/>
Some properties above may be changed or added depending on your needs. The example is for JPA with Hibernate and PostgreSQL database as you may have guessed.
以上某些属性可能会根据您的需要进行更改或添加。您可能已经猜到了JPA与Hibernate和PostgreSQL数据库的示例。
Now you can simply define your data access methods like this:
现在您可以简单地定义数据访问方法,如下所示:
@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);
}
}
where User is a JPA entity defined by your application. You may manager transactions at manager/controller layer that calls your DAOs - in fact I do it that way - but I placed it together here not to clutter example too much.
其中User是您的应用程序定义的JPA实体。您可以在管理器/控制器层管理调用DAO的事务 - 实际上我是这样做的 - 但是我把它放在一起这里并不是太混乱了。
Nice references that you may want to go straight to instead of my examples is http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html The top 3 links it references are worth going to as well.
您可能希望直接参考而不是我的示例的好参考是http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html它引用的前三个链接值得去同样。
#1
10
Spring provides at least 3 ways of transaction demarcation:
Spring提供至少3种事务划分方式:
1) Programmatic handling, via TransactionTemplate or PlatformTransactionManager - light on config, but invasive
1)通过TransactionTemplate或PlatformTransactionManager进行编程处理 - 点亮配置,但是入侵
2) Declarative via XML - verbose XML, but non-invasive
2)通过XML声明 - 详细XML,但非侵入性
3) Declarative via annotations - light on XML, not invasive
3)通过注释声明 - 点亮XML,而不是侵入性
Which one you pick depends on which one best suits your needs, Spring doesn't make that choice for you. From your question, it sounds like the annotation approach is what you're after.
您选择哪一个取决于哪一个最适合您的需求,Spring不会为您做出选择。从您的问题来看,听起来就像注释方法就是您所追求的。
I suggest reading the Spring reference manual, the section of annotation-driven transaction handling. It's clear and concise.
我建议阅读Spring参考手册,注释驱动的事务处理部分。它简洁明了。
I always consult the ref docs first, and only consult a book if it's not in the docs.
我总是先咨询参考文档,如果它不在文档中,则只查阅一本书。
#2
11
There is some work you are supposed to do to be able to do just that but it's not much at all. Supposedly, you will use JPA with pick your own provider, e.g. Hibernate. Then you need to place persistence.xml that defines the persistence unit in the META-INF folder:
你应该做一些工作才能做到这一点,但它根本不是很多。据推测,您将使用JPA选择您自己的提供商,例如休眠。然后,您需要在META-INF文件夹中放置定义持久性单元的persistence.xml:
<?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>
Next, define everything necessary for database connection in the Spring application context you use, at minimum it should contain these:
接下来,在您使用的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"/>
Some properties above may be changed or added depending on your needs. The example is for JPA with Hibernate and PostgreSQL database as you may have guessed.
以上某些属性可能会根据您的需要进行更改或添加。您可能已经猜到了JPA与Hibernate和PostgreSQL数据库的示例。
Now you can simply define your data access methods like this:
现在您可以简单地定义数据访问方法,如下所示:
@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);
}
}
where User is a JPA entity defined by your application. You may manager transactions at manager/controller layer that calls your DAOs - in fact I do it that way - but I placed it together here not to clutter example too much.
其中User是您的应用程序定义的JPA实体。您可以在管理器/控制器层管理调用DAO的事务 - 实际上我是这样做的 - 但是我把它放在一起这里并不是太混乱了。
Nice references that you may want to go straight to instead of my examples is http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html The top 3 links it references are worth going to as well.
您可能希望直接参考而不是我的示例的好参考是http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html它引用的前三个链接值得去同样。