【问题标题】:Spring/Hibernate project @Transactional annotation value is not used and substituted automaticallySpring/Hibernate项目@Transactional注解值不使用,自动替换
【发布时间】:2015-10-12 13:45:54
【问题描述】:

项目中的spring 4/hibernate 4和xml数据库配置有问题。 数据库分为2个。@Transactional指定了错误的transactionManager,但是hibernate连接到正确的数据库而没有抛出任何异常。 Dao 方法使用 @Transactional 注释,如下所示:

@Repository
public class SampleDao {

    @Transactional("database2TransactionManager")
    public SamplePojo getSamplePojo(String smth) {
    database1SessionFactory.getCurrentSession().createCriteria(SamplePojo.class)
        //some code
    }
}

假设SampleDao.getSamplePojo() 实际上是从由 database1TransactionManager 定义的 database1 中获取数据。在这种情况下,@Transactional 值被忽略,而使用 database1TransactionManager。

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#tx-multiple-tx-mgrs-with-attransactional

是否可以将查询限制为使用@Transactional 指定的 transactionManager 而不是任何其他,即使它抛出异常。即使@Transactional 指定带有拼写错误的名称作为事务管理器。

数据库.xml:

<tx:annotation-driven transaction-manager="database1TransactionManager"/>
<tx:annotation-driven transaction-manager="database2TransactionManager"/>

<!--  Database related configuration  -->
<bean id="database1DataSource" destroy-method="close">
//properties
</bean>

<!--  Database related configuration  -->
<bean id="database2DataSource" destroy-method="close">
//properties
</bean>

<bean id="database1SessionFactory" name="database1SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" depends-on="database1DataSource">
//properties
</bean>

<bean id="database2SessionFactory" name="database2SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" depends-on="database2DataSource">
//properties
</bean>

<bean id="database1TransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" depends-on="database1SessionFactory">
    <property name="sessionFactory" ref="database1SessionFactory"/>
    <qualifier value="database1TransactionManager"/>
</bean>

<bean id="database2TransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" depends-on="database2SessionFactory">
    <property name="sessionFactory" ref="database2SessionFactory"/>
    <qualifier value="database2TransactionManager"/>
</bean>

我使用单独的数据库,因此显示此类错误并且我知道它们很重要,而不是 Spring 4 自动进行一些替换。 我做了一些调试,这就是我发现的。有一个用@Transactional 标记的DAO 方法,为它指定了database2TransactionManager。然而,database2TransactionManager 无论如何不能在这个方法中使用,因为它是通过database1SessionFactory 访问的。这些是具有不同用户等的 2 个独立数据库。所以实际上,Spring 不使用 database2TransactionManager,它被来自 database1SessionFactory 的值替换。所以发现有错误的@Transactional 配置,它仍然可以通过spring交互工作。

【问题讨论】:

  • 对于初学者来说,删除&lt;tx:annotation-driven /&gt; 元素之一无论如何只有一个是有效的。但是,您不可能拥有一个默认事务管理器,或者需要明确指定要使用的事务管理器。您真的需要 2 个会话工厂和 2 个事务管理器,还是您只认为需要它们?
  • @M.Deinum 我们不能有多个事务管理器吗?他有单独的预选赛。参考:docs.spring.io/spring/docs/current/spring-framework-reference/…
  • 可以,但您只能拥有 1 个&lt;tx:annotation-driven /&gt;。这仅用于启用@Transactional 并告诉默认使用哪个 tx-manager。在这种情况下,最后一个获胜,database2TransactionManager 将是默认值(即对于没有指定特定值的@Transactional,将使用这个)。事务管理器的数量不影响&lt;tx:annotation-driven /&gt; 元素的数量。拥有多个根本没有意义......
  • 我做了一些调试,这就是我发现的。有一个用@Transactional 标记的DAO 方法,为它指定了database2TransactionManager。但是,database2TransactionManager 无论如何都不能在此方法中使用,因为它是通过 database1SessionFactory 访问的
  • Pavel,但是 Spring 怎么知道要使用哪个事务管理器呢?它是否尝试从会话工厂推断正在使用什么?您可以在示例中清楚地看到,有两台不同的机器具有不同的数据库/方案,一个方法被标记为使用 database1TransactionManager (连接到 database1 数据源),但是 hibernate session factory 用于数据库 2。所以我们有这里有两笔交易?一个用于 database1,它在调用方法时启动,一个用于 database2,它在使用数据库 2 的会话工厂时启动?

标签: java spring hibernate spring-mvc transactions


【解决方案1】:

感谢大家。决定我真的不需要任何 Spring Transaction Synchronisation。 我将此添加到 database.xml:

属性名称="transactionSynchronization" value="2"

现在,如果@Transactional 值不正确,则会引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2021-12-24
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多