gpt4 book ai didi

spring - 对于 web MVC Spring 应用程序应该 @Transactional 继续 Controller 或服务?

转载 作者:IT老高 更新时间:2023-10-28 13:52:46 27 4
gpt4 key购买 nike

对于 WebApplicationContext,我应该输入 @Transactional Controller 或服务中的注释? Spring 文档让我有点困惑。

这是我的 web.xml:

<?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/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Alpha v0.02</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

这是我的 application-context.xml 定义一个 spring dispatcher servlet:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<context:annotation-config />
<mvc:annotation-driven />
<tx:annotation-driven />

<context:component-scan base-package="com.visitrend" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.postgresql.Driver" />
<property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="user" value="someuser" />
<property name="password" value="somepasswd" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:test.hibernate.cfg.xml" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>

这是一个服务接口(interface):

public interface LayerService {
public void createLayer(Integer layerListID, Layer layer);
}

这是一个服务实现:

@Service
public class LayerServiceImpl implements LayerService {

@Autowired
public LayerDAO layerDAO;

@Transactional
@Override
public void createLayer(Integer layerListID, Layer layer) {
layerDAO.createLayer(layerListID, layer);
}
}

这是我的 Controller :

@Controller
public class MainController {

@Autowired
private LayerService layerService;

@RequestMapping(value = "/addLayer.json", method = RequestMethod.POST)
public @ResponseBody
LayerListSetGroup addLayer(@RequestBody JSONLayerFactory request) {
layerService.createLayer(request.getListId(), request.buildLayer());
return layerService.readLayerListSetGroup(llsgID);
}
}

Spring 文档让我有些困惑。这似乎表明使用 WebApplicationContext 意味着只有 Controller 将被调查 @Transactional 注释而不是服务。同时,我看到大量建议使服务具有事务性,而不是 Controller 。我在想使用 <context:component-scan base-package="com..." />在我们上面的 spring-servlet.xml 中,它包含服务包意味着服务是上下文的一部分,因此将被“调查”用于事务注释。这准确吗?

这是让我感到困惑的 Spring 文档简介:

@EnableTransactionManagement and only looks for @Transactional on beans in the same application context they are defined in. This means that, if you put annotation driven configuration in a WebApplicationContext for a DispatcherServlet, it only checks for @Transactional beans in your controllers, and not your services.

此外,如果我将 Controller 方法定义为事务性的,并且它在另一个类中调用事务性方法,是否会产生任何性能影响或“不良”?根据文档,我的预感是否定的,但我希望对此进行验证。

最佳答案

没有要求@Transactional注释应该放在 Controller 或服务上,但通常它会放在一个服务上,该服务将为一个请求执行逻辑,逻辑上应该在一个 ACID 事务中执行。

在典型的 Spring MVC 应用程序中,您至少会有两个上下文:应用程序上下文和 servlet 上下文。上下文是一种配置。应用程序上下文包含与您的整个应用程序相关的配置,而 servlet 上下文包含仅与您的 servlet 相关的配置。因此,servlet 上下文是应用程序上下文的子项,可以引用应用程序上下文中的任何实体。反过来是不正确的。

在您的报价中,

@EnableTransactionManagement and only looks for @Transactional on beans in the same application context they are defined in. This means that, if you put annotation driven configuration in a WebApplicationContext for a DispatcherServlet, it only checks for @Transactional beans in your controllers, and not your services.

@EnableTransactionManagement寻找 @Transactional@ComponentScan 中声明的包中的 bean 中注释,但仅在上下文( @Configuration )中定义它们。所以如果你有一个 WebApplicationContext为您的DispatcherServlet (这是一个 servlet 上下文),然后是 @EnableTransactionManagement将寻找 @Transactional在您告诉它在该上下文中进行组件扫描的类中(@Configuration 类)。

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "my.servlet.package")
public class ServletContextConfiguration {
// this will only find @Transactional annotations on classes in my.servlet.package package
}

自从您的@Service类是应用程序上下文的一部分,如果你想让这些事务性,那么你需要注释你的 @Configuration具有 @EnableTransactionManagement 的应用程序上下文类.

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "my.package.services")
public class ApplicationContextConfiguration {
// now this will scan your my.package.services package for @Transactional
}

将您的应用程序上下文配置与 ContextLoaderListener 一起使用以及实例化 DispatcherServlet 时的 Servlet 上下文配置。 (See the javadoc 用于完整的基于 java 的配置,而不是 xml,如果您还没有这样做的话。)

附录: @EnableTransactionManagement具有与 <tx:annotation-driven /> 相同的行为在java配置中。 Check here使用 ContextLoaderListener使用 XML。

关于spring - 对于 web MVC Spring 应用程序应该 @Transactional 继续 Controller 或服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15620355/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com