你参考下JBOSS XA数据源
standalone.xml
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
h2
sa
sa
localhost
MYDB_ONE
cursor
com.microsoft.sqlserver.jdbc.SQLServerXADataSource
sqljdbc
false
some_user
some_password
localhost
MYDB_TWO
cursor
com.microsoft.sqlserver.jdbc.SQLServerXADataSource
sqljdbc
false
some_user
some_password
org.h2.jdbcx.JdbcDataSource
com.microsoft.sqlserver.jdbc.SQLServerDriver
org.postgresql.xa.PGXADataSource
springJpaConfig.xml
DatasourceRegisteringBeanFactoryPostProcessor.java
package some.package
class DatasourceRegisteringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
HashMap connectionsListMyDB = new HashMap<>();
// Load your connection list from wherever you need to, you can
// enumerate them directly from JNDI or some configuration location
connectionsListMyDB.put("db1", "java:jboss/datasources/MYDB_ONE");
connectionsListMyDB.put("db2", "java:jboss/datasources/MYDB_TWO");
if (connectionsList.isEmpty())
throw new RuntimeException("No JPA connections defined");
// Configure the dataSource bean properties
BeanDefinitionRegistry factory = (BeanDefinitionRegistry) beanFactory;
MutablePropertyValues mpv = factory.getBeanDefinition("dataSourceMyDB").getPropertyValues();
ManagedMap mm = (ManagedMap) mpv.getPropertyValue(
"targetDataSources").getValue();
mm.clear();
for (Entry e : connectionsListMyDB.entrySet()) {
mm.put(e.getKey(), e.getValue());
}
}
}
AbstractRoutingDataSourceMyDB.java
public class AbstractRoutingDataSourceMyDB extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return getDbConnectionMyDB();
}
// ThreadLocal variable so that the connection gets set for the current thread
// using spring""s request scope on the class instead of ThreadLocal would also work here.
private final ThreadLocal contextHolder = new ThreadLocal();
public void setDbConnectionMyDB(String myKey) {
Assert.notNull(myKey, "myKey cannot be null");
contextHolder.set(myKey);
String k = contextHolder.get();
}
public String getDbConnectionMyDB() {
return (String) contextHolder.get();
}
public void clearDbConnectionMyDB() {
contextHolder.remove();
}
}
SomeTableDAO.java
@PersistenceContext(unitName = "MyDB")
private EntityManager em;
@Autowired
private AbstractRoutingDataSourceMyDB routingSource;
public void someMethod(int id) {
em.flush();
em.clear();
routingSource.setDbConnectionMyDB("db1");
em.remove(em.getReference(Something.class, id)); // delete something in db1
em.flush();
em.clear();
routingSource.setDbConnectionMyDB("db2");
em.remove(em.getReference(Something.class, id)); // delete something else with the same id in db2
}