gpt4 book ai didi

hibernate - Spring + Hibernate SessionFactory + AbstractRoutingDataSource

转载 作者:行者123 更新时间:2023-12-02 23:35:23 24 4
gpt4 key购买 nike

我有一个 Spring+Hibernate/Flex 应用程序,需要在数据库模式之间动态切换。为了实现这一点,我在this之后实现了一个AbstractRoutingDataSource。文章。不幸的是它不起作用。它实际上在默认模式(逻辑公共(public))中执行SQL。任何帮助将不胜感激。谢谢。

这是我的设置:

applicationContext.xml 包含两个数据源。每个数据源使用不同的登录角色连接到数据库。路由数据源使用 String 键选择正确的数据源。 SchemaConstants 类包含几个public static final 字段。

<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.postgresql.Driver"/>
<property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/mystore"/>
<property name="acquireIncrement" value="3"/>
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="15"/>
<property name="maxStatementsPerConnection" value="100"/>
<property name="automaticTestTable" value="c3p0_test_table"/>
<property name="numHelperThreads" value = "20"/>
</bean>

<bean id="publicDS" parent="parentDataSource">
<property name="user" value="postgres"/>
<property name="password" value="password"/>
</bean>

<bean id="tempSchemaDS" parent="parentDataSource">
<property name="user" value="temp_role"/>
<property name="password" value="tmppsw"/>
</bean>

<bean id="routingDS" class="flex.RoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="flex.SchemaConstants.LOGICAL_PUBLIC" value-ref="publicDS"/>
<entry key="flex.SchemaConstants.TEMP_SCHEMA" value-ref="tempSchemaDS"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="publicDS"/>
</bean>

RoutingDataSource 实现:这里没有什么可添加的。

public class RoutingDataSource extends AbstractRoutingDataSource
{
@Override
protected Object determineCurrentLookupKey()
{
return Globals.getSchema();
}

@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException
{
// TODO Auto-generated method stub
return null;
}
}

Globals 类:用于存储和查找数据源键。

public class Globals
{
private static final ThreadLocal<String> schemaHolder
= new ThreadLocal<String>();

public static void setSchema(String schema)
{
schemaHolder.set(schema);
}

public static String getSchema()
{
return schemaHolder.get();
}

public static void clearCustomerType()
{
schemaHolder.remove();
}
}

测试代码:尝试插入几条记录,每条记录都在不同的架构(和不同的表)中

@RemotingInclude
@Transactional
public void test()
{
Globals.setSchema(SchemaConstants.TEMP_SCHEMA);

SomeDataOther someOtherData = new SomeDataOther();
someOtherData.setName("Jorjinio");
this.sessionFactory.getCurrentSession().save(someOtherData);


Globals.setSchema(SchemaConstants.LOGICAL_PUBLIC);

SomeData someData = new SomeData();
someData.setFirstName("Hulio");
someData.setLastName("Julio");
this.sessionFactory.getCurrentSession().save(someData);
}

一个次要问题。在这种情况下保持数据完整性的正确方法是什么?我已经用 @Transactional 属性注释了该方法,但我还不确定这是否会如此轻松地工作。我使用的 transactionManager 类型为 org.springframework.orm.hibernate3.HibernateTransactionManager。我还没有对此事进行任何研究,但如果有人可以提供信息,我也将不胜感激。

最佳答案

很明显,当调用 AbstractRoutingDataSource.getConnection() 时,即当事务绑定(bind)的 Hibernate Session 时,实际上会选择特定的 DataSource被 build 。在您的情况下,当您输入 @Transactional 方法时,就会发生这种情况。

因此,您无法在事务内切换方案。您必须针对不同的方案执行单独的交易。要在同一方法内执行多个事务,您可以使用编程式事务管理 (TransactionTemplate),而不是 @Transactional

关于hibernate - Spring + Hibernate SessionFactory + AbstractRoutingDataSource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7378883/

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