使用入门-数据源配置
- 数据源配置,tddl的入口,从datasource切入
<bean id="tddlDataSource" class="com.taobao.tddl.client.jdbc.TDataSource" init-method="init">
<property name="appName" value="tddl_sample" />
<property name="dynamicRule" value="true"/>
</bean>
- Sequence生成器
<bean id="seqStudent" class="com.taobao.tddl.client.sequence.impl.GroupSequence" init-method="init">
<property name="sequenceDao" ref="idSequenceDao" />
<property name="name" value="seq_Student" />
</bean>
- 指定静态文件,3.0以后支持动态推送
<bean id="myDataSource" class="com.taobao.tddl.client.jdbc.TDataSource" init-method="init">
<property name="appName" value="tddl_sample"/>
<property name="appRuleFile" value="classpath:tddl-rule.xml"/>
<property name="useLocalConfig" value="true"/>
</bean>
myDataSource--分库分表数据源
appName--数据库代号从dba获得
appRuleFile--分库分表配置文件
useLocalConfig--使用本地配置
- Sequence配置: tddl-sequence.xml
<bean id="sequenceDao" class="com.taobao.tddl.client.sequence.impl.GroupSequenceDao" init-method="init">
<!-- appName,必填 -->
<property name="appName" value="CUNTAO_SUPPLIER_APP" />
<!-- 数据源的个数 -->
<property name="dscount" value="1" />
<!-- dbGroupKeys 必填 -->
<!-- 如果在末尾插入"-OFF",该源将被关掉,该源占据的SQL段会被保留" -->
<!-- 当dbGroupKeys中配置的个数小于dbcount的值的时候,默认配置了"-OFF"的源 -->
<property name="dbGroupKeys">
<list>
<value>CUNTAO_SUPPLIER_BODY00_GROUP</value>
</list>
</property>
<!-- 内步长 ,默认为1000,取值在1-100000之间 -->
<property name="innerStep" value="500" />
<!-- 重试次数,在多个groupDataSource的场景下,建议设置成1-2次。默认为2次 -->
<property name="retryTimes" value="2" />
<!-- sequence表的表名 -->
<property name="tableName" value="cuntao_supplier_sequence" />
<!-- 自适应开关 ,默认为false -->
<property name="adjust" value="true" />
</bean>
TDDL分库分表配置bean
tddl-rule.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="vtabroot" class="com.taobao.tddl.interact.rule.VirtualTableRoot" init-method="init">
<property name="defaultDbIndex" value="CUNTAO_SUPPLIER_GROUP"/>
<property name="dbType" value="MYSQL"/>
<property name="tableRules">
<map>
<entry key="cuntao_purchase_order" value-ref="cuntao_purchase_order_bean"/>
<entry key="cuntao_sub_purchase_order" value-ref="cuntao_sub_purchase_order_bean"/>
<entry key="cuntao_logistics_order" value-ref="cuntao_logistics_order_bean"/>
<entry key="cuntao_sub_logistics_order" value-ref="cuntao_sub_logistics_order_bean"/>
</map>
</property>
</bean>
<bean id="cuntao_purchase_order_bean" class="com.taobao.tddl.interact.rule.TableRule">
<property name="dbNamePattern" value="CUNTAO_SUPPLIER_BODY{00}_GROUP"/>
<property name="dbRuleArray">
<value>(#supplier_id,1,256#.longValue() % 10000 % 256).intdiv(32)</value>
</property>
<property name="tbNamePattern" value="cuntao_purchase_order_{0000}" />
<property name="tbRuleArray">
<value>#supplier_id,1,256#.longValue() % 10000 % 256</value>
</property>
</bean>
</beans>
配置项说明
分表总配置VirtualTableRoot:
其中,defaultDbIndex是appgroup,从DBA获取;dbType,数据库类型;tableRules引入各个表的配置
分库分表配置TableRule;其中,dbNamePattern分库规则,大括号会替换成dbRuleArray中的值.
dbRuleArray,分库计算方法,(#supplier_id,1,256#.longValue() % 10000 % 256).intdiv(32)表示以supplier_id为分表键,256张表,8个库所以除以32,我们计算规则取后四位计算所以先模10000.
tbNamePattern分表规则,大括号会替换成tbRuleArray中的值。
dbRuleArray,分表计算方法,#supplier_id,1,256#.longValue() % 10000 % 256 就是分库计算方法不除以32.
sequence生成bean
我们用的sequence是一个单库单表的数据库,即每次使用GroupSequence获取新的seq值来计算id,保证全局各个表不会发生id冲突。
appName,从DBA获得。
dbGroupKeys,所在库名称
tableName,sequence表名,可以使用一个sequence表来计算多个表的id,因为每个表实际只占用一行数据。
name,目标表在sequence表中的key,一般取表名,其实是任意的。
- DefaultSequenceDao源码
public class DefaultSequenceDao implements SequenceDao
{
private static final Log log = LogFactory.getLog(DefaultSequenceDao.class);
private static final int MIN_STEP = 1;
private static final int MAX_STEP = 100000;
private static final int DEFAULT_STEP = 1000;
private static final int DEFAULT_RETRY_TIMES = 150;
private static final String DEFAULT_TABLE_NAME = "sequence";
private static final String DEFAULT_NAME_COLUMN_NAME = "name";
private static final String DEFAULT_VALUE_COLUMN_NAME = "value";
private static final String DEFAULT_GMT_MODIFIED_COLUMN_NAME = "gmt_modified";
private static final long DELTA = 100000000L;
private DataSource dataSource;
private int retryTimes = 150;
private int step = 1000;
private String tableName = "sequence";
private String nameColumnName = "name";
private String valueColumnName = "value";
private String gmtModifiedColumnName = "gmt_modified";
private volatile String selectSql;
private volatile String updateSql;
public SequenceRange nextRange(String name)
throws SequenceException
{
if (name == null) {
throw new IllegalArgumentException("序列名称不能为空");
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 0; i < this.retryTimes + 1; i++) { long oldValue;
long newValue;
try { conn = this.dataSource.getConnection();
stmt = conn.prepareStatement(getSelectSql());
stmt.setString(1, name);
rs = stmt.executeQuery();
rs.next();
oldValue = rs.getLong(1);
if (oldValue < 0L) {
StringBuilder message = new StringBuilder();
message.append("Sequence value cannot be less than zero, value = ").append(oldValue);
message.append(", please check table ").append(getTableName());
throw new SequenceException(message.toString());
}
if (oldValue > 9223372036754775807L) {
StringBuilder message = new StringBuilder();
message.append("Sequence value overflow, value = ").append(oldValue);
message.append(", please check table ").append(getTableName());
throw new SequenceException(message.toString());
}
newValue = oldValue + getStep();
} catch (SQLException e) {
throw new SequenceException(e);
} finally {
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
try
{
conn = this.dataSource.getConnection();
stmt = conn.prepareStatement(getUpdateSql());
stmt.setLong(1, newValue);
stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
stmt.setString(3, name);
stmt.setLong(4, oldValue);
int affectedRows = stmt.executeUpdate();
if (affectedRows == 0)
{
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
else
{
return new SequenceRange(oldValue + 1L, newValue);
}
} catch (SQLException e) { throw new SequenceException(e);
} finally {
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
throw new SequenceException("Retried too many times, retryTimes = " + this.retryTimes);
}
private String getSelectSql() {
if (this.selectSql == null) {
synchronized (this) {
if (this.selectSql == null) {
StringBuilder buffer = new StringBuilder();
buffer.append("select ").append(getValueColumnName());
buffer.append(" from ").append(getTableName());
buffer.append(" where ").append(getNameColumnName()).append(" = ?");
this.selectSql = buffer.toString();
}
}
}
return this.selectSql;
}
private String getUpdateSql() {
if (this.updateSql == null) {
synchronized (this) {
if (this.updateSql == null) {
StringBuilder buffer = new StringBuilder();
buffer.append("update ").append(getTableName());
buffer.append(" set ").append(getValueColumnName()).append(" = ?, ");
buffer.append(getGmtModifiedColumnName()).append(" = ? where ");
buffer.append(getNameColumnName()).append(" = ? and ");
buffer.append(getValueColumnName()).append(" = ?");
this.updateSql = buffer.toString();
}
}
}
return this.updateSql;
}
private static void closeResultSet(ResultSet rs) {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
log.debug("Could not close JDBC ResultSet", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC ResultSet", e);
}
}
private static void closeStatement(Statement stmt)
{
if (stmt != null)
try {
stmt.close();
} catch (SQLException e) {
log.debug("Could not close JDBC Statement", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC Statement", e);
}
}
private static void closeConnection(Connection conn)
{
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
log.debug("Could not close JDBC Connection", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC Connection", e);
}
}
...
- GroupSequenceDao源码
public class GroupSequenceDao implements SequenceDao
{
private static final Log log = LogFactory.getLog(GroupSequenceDao.class);
private static final int MIN_STEP = 1;
private static final int MAX_STEP = 100000;
private static final int DEFAULT_INNER_STEP = 1000;
private static final int DEFAULT_RETRY_TIMES = 2;
private static final String DEFAULT_TABLE_NAME = "sequence";
private static final String DEFAULT_NAME_COLUMN_NAME = "name";
private static final String DEFAULT_VALUE_COLUMN_NAME = "value";
private static final String DEFAULT_GMT_MODIFIED_COLUMN_NAME = "gmt_modified";
private static final int DEFAULT_DSCOUNT = 2;
private static final Boolean DEFAULT_ADJUST = Boolean.valueOf(false);
private static final long DELTA = 100000000L;
private String appName;
private List<String> dbGroupKeys;
private Map<String, DataSource> dataSourceMap;
private boolean adjust = DEFAULT_ADJUST.booleanValue();
private int retryTimes = 2;
private int dscount = 2;
private int innerStep = 1000;
private int outStep = 1000;
private String tableName = "sequence";
private String nameColumnName = "name";
private String valueColumnName = "value";
private String gmtModifiedColumnName = "gmt_modified";
private volatile String selectSql;
private volatile String updateSql;
private volatile String insertSql;
private ConcurrentHashMap<Integer, AtomicInteger> excludedKeyCount = new ConcurrentHashMap(this.dscount);
private int maxSkipCount = 10000;
private boolean useSlowProtect = false;
private int protectMilliseconds = 50;
private ExecutorService exec = Executors.newFixedThreadPool(1);
public void init()
throws SequenceException
{
if (StringUtils.isEmpty(this.appName)) {
SequenceException sequenceException = new SequenceException("appName is Null ");
log.error("没有配置appName", sequenceException);
throw sequenceException;
}
if ((this.dbGroupKeys == null) || (this.dbGroupKeys.size() == 0)) {
log.error("没有配置dbgroupKeys");
throw new SequenceException("dbgroupKeys为空!");
}
this.dataSourceMap = new HashMap();
for (String dbGroupKey : this.dbGroupKeys)
if (!dbGroupKey.toUpperCase().endsWith("-OFF"))
{
TGroupDataSource tGroupDataSource = new TGroupDataSource(dbGroupKey, this.appName);
tGroupDataSource.init();
this.dataSourceMap.put(dbGroupKey, tGroupDataSource);
}
if (this.dbGroupKeys.size() >= this.dscount)
this.dscount = this.dbGroupKeys.size();
else {
for (int ii = this.dbGroupKeys.size(); ii < this.dscount; ii++) {
this.dbGroupKeys.add(new StringBuilder().append(this.dscount).append("-OFF").toString());
}
}
this.outStep = (this.innerStep * this.dscount);
StringBuilder sb = new StringBuilder();
sb.append("GroupSequenceDao初始化完成:\r\n ");
sb.append("appName:").append(this.appName).append("\r\n");
sb.append("innerStep:").append(this.innerStep).append("\r\n");
sb.append("dataSource:").append(this.dscount).append("个:");
for (String str : this.dbGroupKeys) {
sb.append("[").append(str).append("]、");
}
sb.append("\r\n");
sb.append("adjust:").append(this.adjust).append("\r\n");
sb.append("retryTimes:").append(this.retryTimes).append("\r\n");
sb.append("tableName:").append(this.tableName).append("\r\n");
sb.append("nameColumnName:").append(this.nameColumnName).append("\r\n");
sb.append("valueColumnName:").append(this.valueColumnName).append("\r\n");
sb.append("gmtModifiedColumnName:").append(this.gmtModifiedColumnName).append("\r\n");
log.info(sb.toString());
}
private boolean check(int index, long value)
{
return value % this.outStep == index * this.innerStep;
}
public void adjust(String name)
throws SequenceException, SQLException
{
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 0; i < this.dbGroupKeys.size(); i++)
if (!((String)this.dbGroupKeys.get(i)).toUpperCase().endsWith("-OFF"))
{
TGroupDataSource tGroupDataSource = (TGroupDataSource)this.dataSourceMap.get(this.dbGroupKeys.get(i));
try
{
conn = tGroupDataSource.getConnection();
stmt = conn.prepareStatement(getSelectSql());
stmt.setString(1, name);
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
rs = stmt.executeQuery();
int item = 0;
while (rs.next()) {
item++;
long val = rs.getLong(getValueColumnName());
if (!check(i, val))
{
if (isAdjust()) {
adjustUpdate(i, val, name);
} else {
log.error("数据库中配置的初值出错!请调整你的数据库,或者启动adjust开关");
throw new SequenceException("数据库中配置的初值出错!请调整你的数据库,或者启动adjust开关");
}
}
}
if (item == 0)
{
if (isAdjust()) {
adjustInsert(i, name);
} else {
log.error("数据库中未配置该sequence!请往数据库中插入sequence记录,或者启动adjust开关");
throw new SequenceException("数据库中未配置该sequence!请往数据库中插入sequence记录,或者启动adjust开关");
}
}
}
catch (SQLException e) {
log.error("初值校验和自适应过程中出错.", e);
throw e;
} finally {
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
}
private void adjustUpdate(int index, long value, String name)
throws SequenceException, SQLException
{
long newValue = value - value % this.outStep + this.outStep + index * this.innerStep;
TGroupDataSource tGroupDataSource = (TGroupDataSource)this.dataSourceMap.get(this.dbGroupKeys.get(index));
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = tGroupDataSource.getConnection();
stmt = conn.prepareStatement(getUpdateSql());
stmt.setLong(1, newValue);
stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
stmt.setString(3, name);
stmt.setLong(4, value);
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
int affectedRows = stmt.executeUpdate();
if (affectedRows == 0) {
throw new SequenceException(new StringBuilder().append("faild to auto adjust init value at ").append(name).append(" update affectedRow =0").toString());
}
log.info(new StringBuilder().append((String)this.dbGroupKeys.get(index)).append("更新初值成功!").append("sequence Name:").append(name).append("更新过程:").append(value).append("-->").append(newValue).toString());
}
catch (SQLException e) {
log.error(new StringBuilder().append("由于SQLException,更新初值自适应失败!dbGroupIndex:").append((String)this.dbGroupKeys.get(index)).append(",sequence Name:").append(name).append("更新过程:").append(value).append("-->").append(newValue).toString(), e);
throw new SequenceException(new StringBuilder().append("由于SQLException,更新初值自适应失败!dbGroupIndex:").append((String)this.dbGroupKeys.get(index)).append(",sequence Name:").append(name).append("更新过程:").append(value).append("-->").append(newValue).toString(), e);
}
finally
{
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
private void adjustInsert(int index, String name)
throws SequenceException, SQLException
{
TGroupDataSource tGroupDataSource = (TGroupDataSource)this.dataSourceMap.get(this.dbGroupKeys.get(index));
long newValue = index * this.innerStep;
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = tGroupDataSource.getConnection();
stmt = conn.prepareStatement(getInsertSql());
stmt.setString(1, name);
stmt.setLong(2, newValue);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
int affectedRows = stmt.executeUpdate();
if (affectedRows == 0) {
throw new SequenceException(new StringBuilder().append("faild to auto adjust init value at ").append(name).append(" update affectedRow =0").toString());
}
log.info(new StringBuilder().append((String)this.dbGroupKeys.get(index)).append(" name:").append(name).append("插入初值:").append(name).append("value:").append(newValue).toString());
}
catch (SQLException e)
{
log.error(new StringBuilder().append("由于SQLException,插入初值自适应失败!dbGroupIndex:").append((String)this.dbGroupKeys.get(index)).append(",sequence Name:").append(name).append(" value:").append(newValue).toString(), e);
throw new SequenceException(new StringBuilder().append("由于SQLException,插入初值自适应失败!dbGroupIndex:").append((String)this.dbGroupKeys.get(index)).append(",sequence Name:").append(name).append(" value:").append(newValue).toString(), e);
}
finally
{
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
public SequenceRange nextRange(final String name)
throws SequenceException
{
if (name == null) {
log.error("序列名为空!");
throw new IllegalArgumentException("序列名称不能为空");
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
int[] randomIntSequence = RandomSequence.randomIntSequence(this.dscount);
for (int i = 0; i < this.retryTimes; i++) {
for (int j = 0; j < this.dscount; j++) {
boolean readSuccess = false;
boolean writeSuccess = false;
int index = randomIntSequence[j];
if (!((String)this.dbGroupKeys.get(index)).toUpperCase().endsWith("-OFF"))
{
if (this.excludedKeyCount.get(Integer.valueOf(index)) != null) {
if (((AtomicInteger)this.excludedKeyCount.get(Integer.valueOf(index))).incrementAndGet() > this.maxSkipCount) {
this.excludedKeyCount.remove(Integer.valueOf(index));
log.error(new StringBuilder().append(this.maxSkipCount).append("次数已过,index为").append(index).append("的数据源后续重新尝试取序列").toString());
}
}
else
{
final TGroupDataSource tGroupDataSource = (TGroupDataSource)this.dataSourceMap.get(this.dbGroupKeys.get(index));
long oldValue;
long newValue;
try
{
long oldValue;
if ((!this.useSlowProtect) || (this.excludedKeyCount.size() >= this.dscount - 1)) {
conn = tGroupDataSource.getConnection();
stmt = conn.prepareStatement(getSelectSql());
stmt.setString(1, name);
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
rs = stmt.executeQuery();
rs.next();
oldValue = rs.getLong(1);
} else {
FutureTask future = new FutureTask(new Callable()
{
public Long call() throws Exception
{
Connection fconn = null;
PreparedStatement fstmt = null;
ResultSet frs = null;
try {
fconn = tGroupDataSource.getConnection();
fstmt = fconn.prepareStatement(GroupSequenceDao.this.getSelectSql());
fstmt.setString(1, name);
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
frs = fstmt.executeQuery();
frs.next();
return Long.valueOf(frs.getLong(1));
} finally {
GroupSequenceDao.closeResultSet(frs);
frs = null;
GroupSequenceDao.closeStatement(fstmt);
fstmt = null;
GroupSequenceDao.closeConnection(fconn);
fconn = null;
}
}
});
try
{
this.exec.submit(future);
oldValue = ((Long)future.get(this.protectMilliseconds, TimeUnit.MILLISECONDS)).longValue();
} catch (InterruptedException e) {
throw new SQLException("[SEQUENCE SLOW-PROTECTED MODE]:InterruptedException", e);
} catch (ExecutionException e) {
throw new SQLException("[SEQUENCE SLOW-PROTECTED MODE]:ExecutionException", e);
} catch (TimeoutException e) {
throw new SQLException(new StringBuilder().append("[SEQUENCE SLOW-PROTECTED MODE]:TimeoutException,当前设置超时时间为").append(this.protectMilliseconds).toString(), e);
}
}
if (oldValue < 0L) {
StringBuilder message = new StringBuilder();
message.append("Sequence value cannot be less than zero, value = ").append(oldValue);
message.append(", please check table ").append(getTableName());
log.info(message);
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null; continue;
}
if (oldValue > 9223372036754775807L) {
StringBuilder message = new StringBuilder();
message.append("Sequence value overflow, value = ").append(oldValue);
message.append(", please check table ").append(getTableName());
log.info(message);
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null; continue;
}
newValue = oldValue + this.outStep;
if (!check(index, newValue))
{
if (isAdjust()) {
newValue = newValue - newValue % this.outStep + this.outStep + index * this.innerStep;
}
else {
SequenceException sequenceException = new SequenceException(new StringBuilder().append((String)this.dbGroupKeys.get(index)).append(":").append(name).append("的值得错误,覆盖到其他范围段了!请修改数据库,或者开启adjust开关!").toString());
log.error(new StringBuilder().append((String)this.dbGroupKeys.get(index)).append(":").append(name).append("的值得错误,覆盖到其他范围段了!请修改数据库,或者开启adjust开关!").toString(), sequenceException);
throw sequenceException;
}
}
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
catch (SQLException e)
{
log.error(new StringBuilder().append("取范围过程中--查询出错!").append((String)this.dbGroupKeys.get(index)).append(":").append(name).toString(), e);
if (this.excludedKeyCount.size() < this.dscount - 1) {
this.excludedKeyCount.put(Integer.valueOf(index), new AtomicInteger(0));
log.error(new StringBuilder().append("暂时踢除index为").append(index).append("的数据源,").append(this.maxSkipCount).append("次后重新尝试").toString());
}
}
finally
{
closeResultSet(rs);
rs = null;
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
try
{
conn = tGroupDataSource.getConnection();
stmt = conn.prepareStatement(getUpdateSql());
stmt.setLong(1, newValue);
stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
stmt.setString(3, name);
stmt.setLong(4, oldValue);
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0);
int affectedRows = stmt.executeUpdate();
if (affectedRows == 0)
{
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
else
{
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
catch (SQLException e)
{
log.error(new StringBuilder().append("取范围过程中--更新出错!").append((String)this.dbGroupKeys.get(index)).append(":").append(name).toString(), e);
}
finally
{
closeStatement(stmt);
stmt = null;
closeConnection(conn);
conn = null;
}
}
}
}
if (i == this.retryTimes - 2) {
this.excludedKeyCount.clear();
}
}
log.error(new StringBuilder().append("所有数据源都不可用!且重试").append(this.retryTimes).append("次后,仍然失败!").toString());
throw new SequenceException("All dataSource faild to get value!");
}
private String getInsertSql() {
if (this.insertSql == null) {
synchronized (this) {
if (this.insertSql == null) {
StringBuilder buffer = new StringBuilder();
buffer.append("insert into ").append(getTableName()).append("(");
buffer.append(getNameColumnName()).append(",");
buffer.append(getValueColumnName()).append(",");
buffer.append(getGmtModifiedColumnName()).append(") values(?,?,?);");
this.insertSql = buffer.toString();
}
}
}
return this.insertSql;
}
private String getSelectSql() {
if (this.selectSql == null) {
synchronized (this) {
if (this.selectSql == null) {
StringBuilder buffer = new StringBuilder();
buffer.append("select ").append(getValueColumnName());
buffer.append(" from ").append(getTableName());
buffer.append(" where ").append(getNameColumnName()).append(" = ?");
this.selectSql = buffer.toString();
}
}
}
return this.selectSql;
}
private String getUpdateSql() {
if (this.updateSql == null) {
synchronized (this) {
if (this.updateSql == null) {
StringBuilder buffer = new StringBuilder();
buffer.append("update ").append(getTableName());
buffer.append(" set ").append(getValueColumnName()).append(" = ?, ");
buffer.append(getGmtModifiedColumnName()).append(" = ? where ");
buffer.append(getNameColumnName()).append(" = ? and ");
buffer.append(getValueColumnName()).append(" = ?");
this.updateSql = buffer.toString();
}
}
}
return this.updateSql;
}
private static void closeResultSet(ResultSet rs) {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
log.debug("Could not close JDBC ResultSet", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC ResultSet", e);
}
}
private static void closeStatement(Statement stmt)
{
if (stmt != null)
try {
stmt.close();
} catch (SQLException e) {
log.debug("Could not close JDBC Statement", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC Statement", e);
}
}
private static void closeConnection(Connection conn)
{
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
log.debug("Could not close JDBC Connection", e);
} catch (Throwable e) {
log.debug("Unexpected exception on closing JDBC Connection", e);
}
}