Issue 1:
Feature Request

For English only, other languages will not accept.

Please pay attention on issues you submitted, because we maybe need more details.

If no response anymore and we cannot make decision by current information, we will close it.

Please answer these questions before submitting your issue. Thanks!

Is your feature request related to a problem?

NO

Describe the feature you would like.

First of all, we can use DistSQL create two READWRITE_SPLITTING RULE in one logic schema.

eg:

CREATE READWRITE_SPLITTING RULE ms_group_0 (
WRITE_RESOURCE=write_ds,
READ_RESOURCES(read_ds_0,read_ds_1),
TYPE(NAME=random)
);
CREATE READWRITE_SPLITTING RULE ms_group_1(
WRITE_RESOURCE=write_ds,
READ_RESOURCES(read_ds_0,read_ds_1),
TYPE(NAME=random)
);

But when we use select in this logic schema,we can't figure out how to route,because of we have same table in two rules.

And it is not legal, because we cant't have two same table in one schema.

So,can we verify dataSource in ReadWrite-splitting rules? Ensures that a logical schema does not exist the same table and cannot be routed.

Issue 2:
Please answer these questions before submitting your issue. Thanks!

2.0.0.M1

各节点都更新成功

执行操作后,无响应

表t_order

(
ORDER_ID INTEGER not null,
USER_ID INTEGER not null,
STATUS VARCHAR2(50)
)

分片键使用USER_ID，切分至2个数据库实例中，并在2个数据库实例中分别插入order_id=1234数据记录。

并开启多个线程进行更新操作,语句如下

update t_order set status='11111' where order_id='1234'

实例代码

SpringMybatisShardingDatabaseOnlyMain2

/*
* Copyright 1999-2015 dangdang.com.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* </p>
*/

package io.shardingjdbc.example.spring.namespace.mybatis;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
*请求1
1、node1 update test set a=1 where user_id='1'

4、node2 update test set a=1 where user_id='1'
请求2
2、node1 update test set a=1 where user_id='1'
3、node2 update test set a=1 where user_id='1'
*
* 如果按照以上顺序执行时,会不会发生死锁现象
*/
public final class SpringMybatisShardingDatabaseOnlyMain2 {

public static void main(final String[] args) throws SQLException, InterruptedException {
final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("META-INF/mybatisShardingDatabaseOnlyContext.xml");
ExecutorService executors = Executors.newFixedThreadPool(10);
for (int i = 0; i < 2; i++) {
executors.execute(new UpdateRunable(applicationContext));
}
TimeUnit.SECONDS.sleep(10);
executors.shutdown();
while (!executors.isTerminated()){
}
System.out.println("程序结束");

}

public static class UpdateRunable implements Runnable {
ApplicationContext applicationContext;

public UpdateRunable(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}

@Override
public void run() {
DataSource dataSource = (DataSource) applicationContext.getBean("shardingDataSource");
Connection connection = null;
PreparedStatement pre = null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
pre = connection.prepareStatement("update t_order set status='11111' where order_id='1234'");
int c = pre.executeUpdate();
System.out.println("t-name:" + Thread.currentThread().getName() + " c1:" + c);
connection.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

}

mybatisShardingDatabaseOnlyContext.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sharding="http://shardingjdbc.io/schema/shardingjdbc/sharding"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://shardingjdbc.io/schema/shardingjdbc/sharding
http://shardingjdbc.io/schema/shardingjdbc/sharding/sharding.xsd">
<context:component-scan base-package="io.shardingjdbc.example.spring.namespace.mybatis" />

<bean id="demo_ds_0" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
<property name="username" value="t2"/>
<property name="password" value="t2"/>
<property name="maxActive" value="50"/>
</bean>

<bean id="demo_ds_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
<property name="username" value="t1"/>
<property name="password" value="t1"/>
<property name="maxActive" value="50"/>
</bean>
<sharding:standard-strategy id="databaseShardingStrategy" sharding-column="user_id" precise-algorithm-class="io.shardingjdbc.example.spring.namespace.mybatis.algorithm.PreciseModuloDatabaseShardingAlgorithm"/>

<sharding:data-source id="shardingDataSource">
<sharding:sharding-rule data-source-names="demo_ds_0, demo_ds_1">
<sharding:table-rules>
<sharding:table-rule logic-table="t_order" database-strategy-ref="databaseShardingStrategy" generate-key-column="order_id" />
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="shardingDataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="shardingDataSource"/>
<property name="mapperLocations" value="classpath*:META-INF/mappers/*.xml"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="io.shardingjdbc.example.spring.namespace.mybatis"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

</beans>

OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.shardingjdbc.example.spring.namespace.mybatis.repository.OrderRepository">
<update id="createIfNotExistsTable">
CREATE TABLE t_order (order_id INT , user_id INT NOT NULL, status VARCHAR2(50), PRIMARY KEY (order_id))
</update>

<update id="truncateTable">
TRUNCATE TABLE t_order
</update>

<update id="dropTable">
DROP TABLE t_order
</update>

<insert id="insert" useGeneratedKeys="true" keyProperty="orderId">
INSERT INTO t_order (
user_id, status
)
VALUES (
#{userId,jdbcType=INTEGER},
#{status,jdbcType=VARCHAR}
)
</insert>

<delete id="delete">
DELETE FROM t_order WHERE order_id = #{orderId,jdbcType=INTEGER}
</delete>
</mapper>