好尝试在google和此处查找,但失败。以下是我的故事:
问题:我有方法保存(…)使用@Transactional(传播=传播。需要\u NEW)注释。但未创建事务。
其他发现:1)当我使用来自其他服务的@Transactional方法进行注释时,正在创建事务。
21:49:13.397 [DEBUG] (http-8080-2) org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [com.xen.components.page.PageServiceImpl.findAllOrdered]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2)此方法所在的服务被代理包装(我在调试中看到),并且从控制器调用方法,因此调用通过代理。
3)根应用程序上下文中的两个服务。log.error(上下文)的输出:
OrderServiceImpl - Root WebApplicationContext: startup date [Tue Sep 17 21:48:30 FET 2013]; root of context hierarchy
PageServiceImpl - Root WebApplicationContext: startup date [Tue Sep 17 21:48:30 FET 2013]; root of context hierarchy
以下是方法代码:
@Service
public class OrderServiceImpl extends CRUDServiceImpl<Order> implements OrderService {
private static final Logger log = Logger.getLogger(OrderServiceImpl.class);
@Autowired
private OrderRepository repo;
@Autowired
private OrderItemService orderItemService;
@Override
protected CRUDRepository<Order> getRepository() {
return repo;
}
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public Order save(Order entity) {
if (entity.getCreationDate() == null) {
entity.setCreationDate(new Date());
}
if (entity.getId() == null) {
increasePopularityForProductsInOrder(entity);
// throws NoTransactionException: No transaction aspect-managed TransactionStatus in scope
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
decreaseStockNumberForSkusInOrder(entity);
}
return super.save(entity);
}
private void increasePopularityForProductsInOrder(Order order) {
List<OrderItem> items = order.getItems();
for (OrderItem item : items) {
orderItemService.increasePopularity(item);
}
}
private void decreaseStockNumberForSkusInOrder(Order order) {
List<OrderItem> items = order.getItems();
for (OrderItem item : items) {
orderItemService.removeFromStock(item);
}
}
}
从控制器调用此方法。控制器代码很简单,只有验证和orderService.save(...)调用。这是我的配置:
应用程序上下文。xml
<beans>
<context:annotation-config />
<context:component-scan base-package="com.xen">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${database.url}" />
<property name="driverClassName" value="${database.driverClassName}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven proxy-target-class="true"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<jpa:repositories base-package="com.xen" />
</beans>
ServletContext.xml
<context:annotation-config />
<context:component-scan base-package="com.xen" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<mvc:annotation-driven />
<mvc:resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**"/>
<mvc:default-servlet-handler/>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.xen.common.util.PagePopulationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/application" p:fallbackToSystemLocale="false"/>
<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>
<bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="error">
<property name="warnLogCategory" value="stdout" />
<property name="exceptionMappings">
<props>
<prop key=".NoSuchRequestHandlingMethodException">404</prop>
<prop key=".NotFoundException">404</prop>
</props>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<value>/WEB-INF/views/**/views.xml</value>
</list>
</property>
</bean>
</beans>
坚持。xml
<persistence>
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>
</persistence>
更新:CartController。JAVA
@Controller
public class CartController {
private static final Logger log = Logger.getLogger(CartController.class);
...
@RequestMapping(value = "/cart/submit-order", method = RequestMethod.POST)
public String submit(@RequestParam String email, @RequestParam long deliveryType, Model uiModel, HttpServletRequest request, RedirectAttributes redirectAttrs) {
Order order = CartHelper.getOrderFromRequest(request);
uiModel.addAttribute("email", email);
// 1. check if address is set
if (StringUtil.isEmpty(order.getClientInfo().getFirstName())) {
MessageBean.createErrorMessage("cart.enter-address.error").displayMessage(uiModel);
populateForm(uiModel, order);
return "cart";
}
// 2. check if specified deliveryType exist
DeliveryType type = null;
try {
type = deliveryTypeService.findOne(deliveryType);
} catch (NotFoundException nfe) {
MessageBean.createErrorMessage("cart.invalid-delivery-type.error").displayMessage(uiModel);
populateForm(uiModel, order);
return "cart";
}
order.setDeliveryType(type);
// 3. check if email is valid
if (!StringUtil.isEmailValid(email)) {
MessageBean.createErrorMessage("cart.invalid-email.error").displayMessage(uiModel);
populateForm(uiModel, order);
return "cart";
}
order.getClientInfo().setEmail(email);
// 4. check if order is not empty
if (order.isEmpty()) { // should not be possible
log.warn("Empty order submission registered! " + order);
return "cart/empty";
}
order = orderService.save(order);
CartHelper.updateOrderForRequest(request, order);
// 5. send notification to client
try {
sendNotificationToClient(order, request);
redirectAttrs.addFlashAttribute(MessageBean.MESSAGE_BEAN_KEY, MessageBean.createSuccessMessage("cart.order.successfuly.created"));
} catch (Exception e) {
redirectAttrs.addFlashAttribute(MessageBean.MESSAGE_BEAN_KEY, MessageBean.createErrorMessage("cart.failed.to.send.notification.during.order.saving"));
}
return "redirect:/orders/success";
}
...
}
如果你有什么想法,请发布它。我对此感到疯狂。
初始化注释时,请尝试指定事务管理器,以便更新配置文件,如下所示:
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
希望这有帮助。
我正在使用注释处理器来处理方法参数的注释。 用于参数的注释类型有一个注释@参数 现在,当注释处理器运行时,我想检查参数注释()是否有参数注释。我通过执行以下代码来实现这一点。 由于某种原因,arg始终为空。是否有注释未返回的原因?
问题内容: 美好的一天。如下代码: 据我了解,如果方法中存在异常,则不会回滚事务。以及如何使它滚动?并返回SomeResult 问题答案: 您不应该以编程方式调用回滚。根据docs的建议,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。 在你的情况下,像这样 看一下@Transaction API 和有关回滚事务的文档。 如果尽管有文档建议,但仍要进行程序化回滚,则需要按照已建议的
当使用带有类级注释的Spring AOP时,Spring似乎总是为每个类创建并返回一个代理或拦截器,不管它们是否有注释。 此行为仅用于类级注释。对于方法级注释或执行切入点,如果不需要拦截,返回一个POJO。 这是虫子吗?按设计?还是我做错了什么?
问题内容: 是否存在列注释语法,该语法允许我直接在创建表语句(即,内联)中声明列的位置指定列注释?该11克规范没有提到任何东西,在另一页中提到的东西,但我无法得到它的工作。创建表后有一种指定注释的方法,但是我认为将注释与字段定义分开很烦人。我正在寻找这样的东西(不起作用): 问题答案: 恐怕“烦人”的语法是这样做的唯一方法。SQL Server,PostgreSQL和DB2使用相同的语法(尽管据我
spring应用程序无法启动,因为它无法在配置类中找到一个带有@Service注释的类的bean。但只有在我使用@Transactional注释特定服务类中的方法时才会出现这种情况。为什么会这样?
我有一个如下所示的基类: 我想创建一个具有以下功能的只读包装类: 更确切地说,我希望类的所有字段都是只读的,但只有在调用之后,否则类就不能在构造函数本身中构造。我知道可以使用属性装饰器来完成,但我不想把所有属性都变成属性。