交易“必需"Spring中的传播 [英] Transaction "REQUIRED" propagation in Spring

查看:26
本文介绍了交易“必需"Spring中的传播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Spring 的新手,无法在必需"模式下进行事务传播.

I'm new to Spring and I'm not able to make the transaction propagation in "REQUIRED" mode.

这是一个例子:

@Controller
public class ExampleController
{
    @Autowired
    Foo foo;

    @Autowired
    Bar bar;

    @RequestMapping(value = "/example")
    public String submitForm(Model model) throws Exception
    {
        User user = new User("Joe", "Bloggs");
        user = foo.save(user);
        bar.simpleMethod(user);
        return "success";
    }
}

<小时>

@Repository
public class Foo
{
    // A JPA repository
    private EntityManager em;

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public User save(User user)
    {
        return this.em.merge(user);
    }

    @PersistenceContext
    void setEntityManager(EntityManager entityManager)
    {
        this.em = entityManager;
    }
}

<小时>

public class Bar
{
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void simpleMethod(User user)
    {
        // Do something...
    }
}

applicationContext.xml(重要部分):

The applicationContext.xml (important bits):

<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: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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    <context:property-placeholder location="/WEB-INF/jdbc.properties" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <constructor-arg>
            <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="${db.driverClassName}" />
                <property name="url" value="${db.url}" />
                <property name="username" value="${db.username}" />
                <property name="password" value="${db.password}" />
            </bean>
        </constructor-arg>
    </bean>

    <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
        <property name="showSql" value="${db.showSql}" />
        <property name="generateDdl" value="${db.generateDdl}" />
    </bean>

    <!-- enabling annotation driven configuration /-->
    <context:annotation-config />
    <context:component-scan base-package="my.package" />

    <!-- Instructs the container to look for beans with @Transactional and decorate them -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

    <!-- FactoryBean that creates the EntityManagerFactory  -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaVendorAdapter" ref="jpaAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- A transaction manager for working with JPA EntityManagerFactories -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
</beans>

如果 bar.simpleMethod() 中出现异常,foo.save(...) 不会回滚(或者可能是,但数据库是当然不是).有谁知道为什么?

If an exception occours in bar.simpleMethod(), foo.save(...) is not rolled back (or maybe it is, but the database is certainly not). Does anyone know why?

推荐答案

如果bar.simpleMethod()发生异常,foo.save(...)不会回滚

两者都不应该 - 您已经将事务注释单独包装在 Bar.simpleMethodFoo.save 周围,因此这些将作为两个单独的事务执行.如果 Bar.simpleMethod 失败,它会回滚自己的事务,但 Foo.save 的事务已经提交.没有涵盖两者的单一交易.

And neither it should be - you've wrapped your transaction annotations individually around Bar.simpleMethod and Foo.save, and so these will be performed as two separate transactions. If Bar.simpleMethod fails, it rolls back its own transaction, but Foo.save's transaction has already been committed. There's no single transaction covering both.

您需要将这两个操作封装在一个方法中,该方法在单个事务中执行这两个操作.这最好通过引入一个由控制器调用的额外组件来完成.此方法将使用 @Transactional 进行注释,并执行 Bar.simpleMethodFoo.save.Bar.simpleMethodFoo.save 上的 @Transactional 注释将成为同一整体事务的一部分.

You need to encapsulate the two operations within a method that performs both operations in a single transaction. This is best done by introducing an extra component, which is invoked by the controller. This method would be annotated with @Transactional, and performs Bar.simpleMethod and Foo.save. The @Transactional annotations on Bar.simpleMethod and Foo.save will be made part of the same overall transaction.

这篇关于交易“必需"Spring中的传播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆