gpt4 book ai didi

java - 尝试同时保存到两个数据库时,找不到当前线程的 session 错误

转载 作者:行者123 更新时间:2023-11-29 05:20:13 25 4
gpt4 key购买 nike

您好,我正在尝试同时保存到两个数据库中,但我总是遇到错误。

Exception in thread "main" org.hibernate.HibernateException: No Session found for current thread

这是我的代码:

@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW, readOnly=false)
public void save(ArsenalPlayer domain1, ArsenalPlayer2 domain2)
throws Exception {

dao1.save(domain1);
dao2.save(domain2);

}
  • dao1 使用附加到 datasource1 的 sessionFactory
  • dao2 使用附加到 datasource2 的 sessionFactory

这是我的配置

数据源

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/arsenal" />
<property name="user" value="root" />
<property name="password" value="ahmids" />
</bean>

session 工厂

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

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">update</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>

<property name="annotatedClasses">
<list>
<value>com.gongfu4.bean.ArsenalPlayer</value>
</list>
</property>
</bean>

数据源2

<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/arsenal2" />
<property name="user" value="root" />
<property name="password" value="ahmids" />
</bean>

session 工厂2

<bean id="sessionFactory2"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">update</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
</props>
</property>

<property name="annotatedClasses">
<list>
<value>com.gongfu4.bean.ArsenalPlayer2</value>
</list>
</property>
</bean>

应用上下文

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

<context:annotation-config />

<import resource="dataSource.xml" />
<import resource="dataSource2.xml" />
<import resource="hibernate.xml" />
<import resource="hibernate2.xml" />

<tx:annotation-driven />

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

<bean id="myTx"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2" />
</bean>

这是我的 dao 类:

DAO1

@Autowired
SessionFactory sessionFactory;

public void save(ArsenalPlayer domain) {
sessionFactory.getCurrentSession().save(domain);
}

DAO2

@Autowired
SessionFactory sessionFactory2;

public void save(ArsenalPlayer2 domain) {
sessionFactory2.getCurrentSession().merge(domain);
}

我的配置有问题吗?

最佳答案

您不能那样使用这两个事务管理器。你有两个数据源,两个事务管理器,从你的代码中,我了解到你希望在同一个事务中执行两个保存操作。问题是“来自哪个事务管理器的事务?”。

您拥有代码和配置的方式,Spring 将使用“默认”事务管理器,因为 <tx:annotation-driven/>默认情况下将搜索 ID 为“transactionManager”的事务管理器 bean,具有此 ID 的 bean 是数据源 dataSource 的那个。 .但是您的代码不起作用,这是预期的行为。 Spring 将使用 sessionFactory 打开一个 Hibernate session 和 dao1.save(domain1);调用将成功,因为这是正确数据源的正确 Hibernate session 。但是当dao2.save(domain2);方法被调用,您将拥有来自 dao1 的相同 session 调用但用于第二个数据库的数据库操作。

在我看来,您有两个选择:

  1. 使用 JTA 事务管理器协调两个数据源。使用 JTA,两个保存操作将是原子的。如果一个失败,则两个都回滚。

  2. 执行两个 save(domain)两个不同事务中的操作正确配置了 @Transactional注释以使用正确的事务管理器。在这种情况下,这两个保存操作将不是原子的。如果一次保存失败,则只会回滚那一次。请参阅下面摘自 Spring 引用文档的豁免 here :

    public class TransactionalService {

@Transactional("order")
public void setSomething(String name) { ... }

@Transactional("account")
public void doSomething() { ... }
}
    <tx:annotation-driven/>

<bean id="transactionManager1" class="org.springframework.jdbc.DataSourceTransactionManager">
...
<qualifier value="order"/>
</bean>

<bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">
...
<qualifier value="account"/>
</bean>

关于java - 尝试同时保存到两个数据库时,找不到当前线程的 session 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25130052/

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