Detail Spring MVC transaction configuration
- 2020-06-23 00:18:37
- OfStack
To understand all the methods for transaction configuration, see the following 5 Methods for Spring Transaction Configuration
This article introduces two configuration methods:
1. XML, using the tx tag to configure the interceptor to implement transactions
2. Annotation way
The following environments are Spring4.0.3 and Hibernate4.3.5
1.XML, using the tx tag to configure the interceptor to implement transactions
Entity class ES22en.java, persistent class, corresponding to database table user
package com.lei.demo.entity;
import javax.persistence.*;
@Entity(name="users")
public class Users {
public Users(){
super();
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
private Integer id;
@Column(name="user_name",length=32)
private String user_name;
@Column(name="age")
private Integer age;
@Column(name="nice_name",length=32)
private String nice_name;
// Properties for ......
}
UserDAO. javar, table user 1, where attribute sessionFactory should be injected by Spring, as follows:
package com.lei.demo.dao;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import com.lei.demo.entity.Users;
public class UsersDAO {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public List<Users> getAllUser(){
String hsql="from users";
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery(hsql);
return query.list();
}
}
UserService.java, business implementation class, as follows
package com.lei.demo.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.lei.demo.dao.*;
public class UserService {
private UsersDAO userDao;
public int userCount(){
return userDao.getAllUser().size();
}
public UsersDAO getUserDao() {
return userDao;
}
public void setUserDao(UsersDAO userDao) {
this.userDao = userDao;
}
}
First, take a look at the xml configuration. spring-hibernate. xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">
<!-- Hibernate4 -->
<!-- Load resource file It contains variable information that must be in Spring The first load of the configuration file, the first 1 A load -->
<context:property-placeholder location="classpath:persistence-mysql.properties" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<!-- Multiple packages can be added -->
<value>com.lei.demo.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
</props>
</property>
</bean>
<!-- Database mapping -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<!-- configuration Hibernate Transaction manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Configure transaction exception encapsulation -->
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- Declarative container transaction management ,transaction-manager Specifies that the transaction manager is transactionManager -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config expose-proxy="true">
<!-- Only the business logic layer is transacted -->
<aop:pointcut id="txPointcut" expression="execution(* com.lei.demo.service..*.*(..))" />
<!-- Advisor Definition, pointcut and advice are, respectively txPointcut , txAdvice -->
<aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>
</aop:config>
</beans>
The main configuration sections are tx:advice and aop:config, which implement transaction management in the way of Spring AOP.
tx:advice configured the transaction manager to be transactionManager, and tx:method also specifies the transaction to be used if the method name matches the "add*" and "get*" methods, and propagation is to set the propagation level of the transaction. With the exception of the "add*" and "get*" methods, all other methods are read-only (typically, you set this property to true for query-only transactions, and read-only transactions fail if updates, inserts, or deletes occur).
aop:config specifies 1 aop:pointcut to refer to advice above.
This enables transactions through the interception mechanism of AOP, and of course you have to configure UserDAO and UserService yourself with Spring.
2. Annotation way
Step 1 first look at web. xml, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>lei-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/lei-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>lei-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Step 2, ES90en-ES91en configuration, see es92EN-ES93en.xml configuration below
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">
<!-- Hibernate4 -->
<!-- Load resource file It contains variable information that must be in Spring The first load of the configuration file, the first 1 A load -->
<context:property-placeholder location="classpath:persistence-mysql.properties" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<!-- Multiple packages can be added -->
<value>com.lei.demo.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
</props>
</property>
</bean>
<!-- Database mapping -->
<!-- class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" -->
<!-- class="org.springframework.jdbc.datasource.DriverManagerDataSource" -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<!-- configuration Hibernate Transaction manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Configure transaction exception encapsulation -->
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
In Section 1, xml configuration transactions need to be added by configuring tx:advice and aop:config. The full annotation approach is used here, so these two configuration sections are not needed.
The corresponding need is to enable annotations in the view parsing configuration, as shown in es105EN-ES106en-ES107en.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">
<!-- Start automatic scanning The package covers all of them Bean(@Controller) -->
<context:component-scan base-package="com.lei.demo" />
<!-- Annotation-based transaction, when found in annotations @Transactional When using id As a" transactionManager " -->
<!-- If it's not set transaction-manager The value of the, then spring Transactions are processed with the default transaction manager as the first 1 Three loaded transaction managers -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Define the view parser -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/user/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
UserDAO as follows
package com.lei.demo.dao;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import com.lei.demo.entity.Users;
@Repository
public class UsersDAO {
@Resource(name="sessionFactory")
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public List<Users> getAllUser(){
String hsql="from users";
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery(hsql);
return query.list();
}
}
UserService java as follows
package com.lei.demo.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.lei.demo.dao.*;
@Service("userService")
public class UserService {
@Resource
private UsersDAO userDao;
@Transactional
public int userCount(){
return userDao.getAllUser().size();
}
public UsersDAO getUserDao() {
return userDao;
}
public void setUserDao(UsersDAO userDao) {
this.userDao = userDao;
}
}
Here, add @Transactional to the method name userCount, indicating that the method is transaction-enabled. If @Transactional is added to the class name UserService, this indicates that all methods in the class will enable transactions.
If you have multiple transactionManager, such as configured with transactionManager1 and transactionManager2, you can specify which data source transaction to use via @ES130en (" transactionManager1 ").