Per WebApplicationContext, dovrei inserire annotazioni @Transactional
nel controller o nei servizi? I documenti di primavera mi hanno un po 'confuso.Per l'applicazione web MVC Spring dovrebbe @Transactional andare su controller o servizio?
Ecco il mio 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>
Qui è la mia domanda-context.xml definizione di una servlet primavera dispatcher:
<?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>
Ecco un'interfaccia di servizio:
public interface LayerService {
public void createLayer(Integer layerListID, Layer layer);
}
Ecco un'implementazione del servizio:
@Service
public class LayerServiceImpl implements LayerService {
@Autowired
public LayerDAO layerDAO;
@Transactional
@Override
public void createLayer(Integer layerListID, Layer layer) {
layerDAO.createLayer(layerListID, layer);
}
}
Ed ecco il mio 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);
}
}
La documentazione Primavera mi ha un po 'confuso. Sembra indicare che l'utilizzo di WebApplicationContext significa che solo i controller verranno esaminati per le annotazioni @Transactional e non per i servizi. Nel frattempo vedo tonnellate di raccomandazioni per rendere i servizi transazionali e non i controllori. Sto pensando che usare <context:component-scan base-package="com..." />
nel nostro servlet.xml di primavera sopra in modo che includa i pacchetti di servizi significa che i servizi fanno parte del contesto, e quindi saranno "studiati" per le annotazioni transazionali. È accurato?
Ecco la fascetta pubblicitaria documentazione di primavera che mi sono confuso:.
@EnableTransactionManagement e guarda solo per @Transactional su fagioli nello stesso contesto applicativo sono definito Questo significa che, se si mette l'annotazione guidato configurazione in un WebApplicationContext per DispatcherServlet, è controlla solo i bean @Transactional nei controller e non i servizi .
Inoltre, ci sono implicazioni di prestazioni o "cattiveria" se definisco un metodo di controllo come transazionale e chiama un metodo transazionale in un'altra classe? La mia impressione è no, basata sulla documentazione, ma mi piacerebbe la convalida su questo.
Sapete perché la documentazione di Spring si riferiva solo alle annotazioni del controllore in lettura? Non sta considerando nessuna scansione dei componenti? Ecco un link ai documenti più recenti in cui ho trovato questo: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations – user2208384
@ user2208384: Ti avverte solo che la scansione troverà solo le cose all'interno dello stesso contesto applicativo. quindi se si desidera annotare servizi, inserire tale configurazione nel contesto dell'applicazione che gestisce i servizi. –
Come si mettono i servizi nello stesso WebApplicationContext? Penso che la scansione dei componenti lo faccia se si includono i pacchetti di servizi, ma si vuole essere sicuri. In altre parole, i miei file di esempio non lo fanno già? – user2208384