我有一个Spring + Hibernate/Flex应用程序需要在数据库模式之间动态切换.为了实现这个目标我实现了一个AbstractRoutingDataSource下面这个文章.不幸的是它不起作用.它实际上在默认模式(logical_public)中执行SQL.任何帮助将不胜感激.谢谢.
这是我的设置:
applicationContext.xml包含两个数据源.每个数据源都使用不同的登录角色连接到数据库.路由数据源使用String键选择正确的数据源.SchemaConstants类包含几个公共静态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>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
测试代码:尝试插入几个记录,每个记录在不同的模式(和不同的表)中
@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);
}
Run Code Online (Sandbox Code Playgroud)
第二个问题.在这种情况下保持数据完整性的正确方法是什么?我已经使用@Transactional属性注释了该方法,但我很难确定这会如此容易地工作.我使用的transactionManager是org.springframework.orm.hibernate3.HibernateTransactionManager类型.我还没有研究过这个问题,但如果有人能提供信息,我们也会非常感激.
很明显,DataSource在AbstractRoutingDataSource.getConnection()调用时,特别是当Session创建了事务绑定的Hibernate时,实际上会选择特定的.在您的情况下,当您输入@Transactional方法时会发生这种情况.
因此,您无法在事务内切换方案.您必须针对不同的方案执行单独的事务.要在同一方法中执行多个事务,您可以使用程序化事务管理(TransactionTemplate)而不是@Transactional.
| 归档时间: |
|
| 查看次数: |
5968 次 |
| 最近记录: |