1. 介绍
介绍如何配置使用多数据源,支持相应的系统功能。未来的多租户模式也需要依赖多数据源功能。
2. 配置
在application.yml中添加配置,注意第二个以上的数据源配置需要使用GORM的写法(dataSource的S字符大写) 下面的示例都是用的M2数据库,可根据实际情况配置为MYSQL或ORACLE
spring:
profiles: development
h2.console.enabled: true
h2.console.path: /dbconsole
datasource:
driverClassName: org.h2.Driver
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
type: com.zaxxer.hikari.HikariDataSource
hikari:
maximum-pool-size: 200
connection-timeout: 60000
connection-test-query: SELECT 1
auto-commit: true
read-only: false
idle-timeout: 600000
max-lifetime: 1800000
minimum-idle: 10
dataSources:
db1:
pooled: true
dbCreate: create-drop
driverClassName: org.h2.Driver
url: jdbc:h2:./db1;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
username: sa
password: sa
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
type: com.zaxxer.hikari.HikariDataSource
properties:
jmxEnabled : true
initialSize : 5
maxActive : 50
minIdle : 5
maxIdle : 25
maxWait : 10000
maxAge : 10 * 60000
timeBetweenEvictionRunsMillis : 5000
minEvictableIdleTimeMillis : 60000
validationQuery : SELECT 1
validationQueryTimeout : 3
validationInterval : 15000
testOnBorrow : true
testWhileIdle : true
testOnReturn : false
jdbcInterceptors : ConnectionState;StatementCache(max=200)
db2:
driverClassName: org.h2.Driver
url: jdbc:h2:./db2;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
username: sa
password: sa
映射具体的domain类到特定的数据源,在mapping闭包中指定。若没有指定,则会映射到第一个数据源(默认数据源)
static mapping = {
datasource 'db2'
}
可使用ConnectionSource类来辅助,指定映射至一个或多个数据源
import org.grails.datastore.mapping.core.connections.ConnectionSource
@Entity
@Title(zh_CN = "图书")
@JsonIgnoreProperties(["errors", "metaClass", "dirty", "attached", "dirtyPropertyNames"])
class Dog implements GormEntity<Dog> {
String name
static constraints = {
name(unique: true)
}
static mapping = {
datasources(['db1', ConnectionSource.DEFAULT])
//datasource ConnectionSource.ALL
}
}
3. 使用
在starup类中使用
//第一个数据源
Dog dog=new Dog(name: "defaultDog");
dog.save(flush:true);
//第二个数据源
Dog.db1.withTransaction {
dog=new Dog(name: "db1-Dog");
dog.db1.save(flush:true);
}
在controller或service中使用,可做多数据源分布式事务,支持两阶段提交
Dog dog=new Dog(name: "db1Dog");
dog.db1.save(flush:true);
Dog.withTransaction {status->
if(dog.save(flush:true) && dog.db1.save(flush: true)){
}else{
status.setRollbackOnly();
//通知aop层事务也标记回滚,避免commit出错
org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
}
}