Ver Código Fonte

@IPU_REQ_0014@weihf@添加ipu-nosql事务控制示例

weihf 4 anos atrás
pai
commit
56dde7c5d4

+ 11 - 0
ipu-rest-demo/pom.xml

@ -32,6 +32,7 @@
32 32
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
33 33
		<ipu>3.1-SNAPSHOT</ipu>
34 34
		<msgframe>1.9.2</msgframe>
35
		<mongo.java.driver>3.11.2</mongo.java.driver>
35 36
		<jms>1.1</jms>
36 37
	</properties>
37 38
@ -65,6 +66,16 @@
65 66
		    <artifactId>ipu-sql-mgmt</artifactId>
66 67
		    <version>${ipu}</version>
67 68
		</dependency>
69
		<dependency>
70
            <groupId>com.ai.ipu</groupId>
71
            <artifactId>ipu-nosql</artifactId>
72
            <version>${ipu}</version>
73
        </dependency>
74
        <dependency>
75
            <groupId>org.mongodb</groupId>
76
            <artifactId>mongo-java-driver</artifactId>
77
            <version>${mongo.java.driver}</version>
78
        </dependency>
68 79
	</dependencies>
69 80
70 81
	<build>

+ 117 - 0
ipu-rest-demo/src/main/java/com/ai/ipu/server/demo/control/mongodb/MongoDbController.java

@ -0,0 +1,117 @@
1
package com.ai.ipu.server.demo.control.mongodb;
2

3
import org.springframework.beans.factory.annotation.Autowired;
4
import org.springframework.stereotype.Controller;
5
import org.springframework.web.bind.annotation.RequestMapping;
6
import org.springframework.web.bind.annotation.ResponseBody;
7

8
import com.ai.ipu.data.JMap;
9
import com.ai.ipu.data.impl.JsonMap;
10
import com.ai.ipu.server.demo.service.MongoServiceImpl;
11

12
/**
13
 * @author weihf@asiainfo.com
14
 * @team IPU
15
 * @date 2020年9月27日下午13:02:22
16
 * @desc 基于ipu-nosql组件对mongodb操作范例
17
 */
18
@Controller
19
@RequestMapping("/mongodb/")
20
public class MongoDbController {
21
	private String connName = "data";
22
	@Autowired
23
	private MongoServiceImpl service;
24
	
25
    /**
26
     * @author weihf@asiainfo.com
27
     * @title: insert
28
     * @desc: 使用mongodb语法插入1条记录,并使用mongodb语法查询插入的记录
29
     */
30
	@ResponseBody
31
    @RequestMapping("/insert")
32
    public JMap insert(JMap param) throws Exception {
33
		JMap result = new JsonMap();
34
        service.processInsertTranscation(connName);
35
        result.put("result", "insert successful");
36
		return result;		
37
    }
38
	
39
    /**
40
     * @author weihf@asiainfo.com
41
     * @title: insertRollback
42
     * @desc: 使用sql语法插入1条记录,然后抛异常回滚插入操作
43
     */
44
	@ResponseBody
45
    @RequestMapping("/insertRollback")
46
    public JMap insertRollback(JMap param) throws Exception {
47
		JMap result = new JsonMap();
48
        service.processRollback(connName);
49
        //永远执行不到这里
50
        result.put("result", "insert error.Rollback successful.");
51
		return result;
52
    }
53
	
54
    /**
55
     * @author weihf@asiainfo.com
56
     * @title: insertMulti
57
     * @desc: 自己控制事务+系统事务。
58
     *        使用sql语法插入1条记录,然后自己控制事务提交;
59
     *        再接着使用sql语法插入2条记录,抛异常,系统事务回滚插入操作,自己提交的事务不回滚。
60
     */
61
	@ResponseBody
62
    @RequestMapping("/insertMulti")
63
    public JMap insertMulti(JMap param) throws Exception {
64
		JMap result = new JsonMap();
65
		service.processMultiTranscation(connName);
66
		//永远执行不到这里
67
		result.put("result", "MultiTranscation successful");
68
		return result;
69

70
    }
71

72
    /**
73
     * @author weihf@asiainfo.com
74
     * @title: delete
75
     * @desc: 使用mongodb语法删除记录;
76
     *        并使用mongodb语法查询被删除记录,查不到表示删除成功。
77
     */
78
	@ResponseBody
79
    @RequestMapping("/delete")
80
    public JMap delete(JMap param) throws Exception {
81
		JMap result = new JsonMap();
82
		service.processDeleteTranscation(connName);
83
		result.put("result", "delete successful");
84
		return result;
85
	}
86

87

88
    /**
89
     * @author weihf@asiainfo.com
90
     * @title: update
91
     * @desc: 使用mongodb语法修改记录,并使用mongodb语法查询被修改的记录
92
     */
93
	@ResponseBody
94
    @RequestMapping("/update")
95
    public JMap update(JMap param) throws Exception {
96
		JMap result = new JsonMap();
97
		service.processUpdateTranscation(connName);
98
		result.put("result", "update successful");
99
		return result;
100

101
	}
102

103
    /**
104
     * @author weihf@asiainfo.com
105
     * @title: query
106
     * @desc: 使用sql语法查询记录
107
     */
108
	@ResponseBody
109
    @RequestMapping("/query")
110
    public JMap query(JMap param) throws Exception {
111
		JMap result = new JsonMap();
112
		result.put("result", service.query(connName));
113
		return result;
114

115
	}
116

117
}

+ 100 - 0
ipu-rest-demo/src/main/java/com/ai/ipu/server/demo/service/MongoServiceImpl.java

@ -0,0 +1,100 @@
1
package com.ai.ipu.server.demo.service;
2

3
import java.util.HashMap;
4
import java.util.List;
5
import java.util.Map;
6

7
import com.ai.ipu.basic.log.ILogger;
8
import com.ai.ipu.basic.log.IpuLoggerFactory;
9

10
import org.springframework.stereotype.Service;
11

12
import com.ai.ipu.nosql.INoSql;
13
import com.ai.ipu.nosql.mongodb.MongoCacheFactory;
14
import com.alibaba.fastjson.JSONObject;
15

16
@Service
17
public class MongoServiceImpl {
18

19
    private ILogger log = IpuLoggerFactory.createLogger(MongoServiceImpl.class);
20

21

22
    public MongoServiceImpl() {
23

24
    }
25

26

27
    public void processRollback(String connName) throws Exception {
28
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
29
        noSql.executeInsert("insert into mycol1 (name, nickName) values ('mongo', 'kevin')");
30

31
        //rollback
32
        noSql.executeInsert("this is rollback test.");
33

34
    }
35

36
    public void processMultiTranscation(String connName) throws Exception {
37
        //操作日志是一个单独事务,不会因为其他事务失败而回退
38
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "oplog");
39
        noSql.executeInsert("insert into oplog (name, operTime, memo) values ('mongo', '2020-09-27 12:35:00', '操作测试')");
40
        //先提交,再关闭
41
        MongoCacheFactory.close(connName, "test", "oplog");
42

43
        //其他事务
44
        noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
45
        noSql.executeInsert("insert into mycol1 (name, nickName) values ('mongo', 'kevin')");
46

47
        noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
48
        noSql.executeInsert("insert into mycol1 (name) values ('mongo')");
49

50
        //rollback
51
        noSql.executeInsert("this is rollback test.");
52

53
    }
54

55
    public void processInsertTranscation(String connName) throws Exception {
56
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
57
        //插入一条数据       
58
        JSONObject data = new JSONObject();
59
        data.put("name", "mongo");
60
        data.put("nickName", "tom2");
61
        Map info = new HashMap();
62
        info.put("ver", 7.1);
63
        data.put("info", info);
64
        noSql.executeInsert(data);
65
        
66
        //查询该刚插入的数据
67
        JSONObject param = new JSONObject();
68
        param.put("name", "mongo");
69
        param = new JSONObject();
70
        param.put("info.ver", 7.1);
71
        log.debug("查询name='mongo' && info.ver=7.1的结果为:[" + noSql.executeSelect(param.toJSONString(), "{}") + "]");
72
    }
73

74

75
    public void processDeleteTranscation(String connName) throws Exception {
76
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
77
        //删除数据
78
        noSql.executeDelete("delete from mycol1 where nickName='tom2'");
79
        
80
        //查询删除的数据
81
        log.debug("查询结果为:" + noSql.executeSelect("select * from mycol1 where nickName='tom2'"));
82
    }
83

84

85
    public void processUpdateTranscation(String connName) throws Exception {
86

87
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
88
        //更新数据
89
        noSql.executeUpdate("update mycol2 set name='jack' where name='mongo' and nickName='tom1'");
90
        
91
        //查询更新的数据
92
        log.debug("查询结果为:" + noSql.executeSelect("select * from mycol1 where name='jack'"));
93
    }
94

95
    public List<String> query(String connName) throws Exception {
96
        INoSql noSql = MongoCacheFactory.getMongoDao(connName, "test", "mycol1");
97
        //查询数据
98
        return noSql.executeSelect("select * from mycol1 where name='mongo'");
99
    }
100
}

+ 41 - 0
ipu-rest-demo/src/main/java/com/ipu/server/aspect/TransactionAspect.java

@ -0,0 +1,41 @@
1
package com.ipu.server.aspect;
2

3
import org.aspectj.lang.ProceedingJoinPoint;
4
import org.aspectj.lang.annotation.Around;
5
import org.aspectj.lang.annotation.Aspect;
6
import org.aspectj.lang.annotation.Pointcut;
7

8
import com.ai.ipu.basic.log.ILogger;
9
import com.ai.ipu.basic.log.IpuLoggerFactory;
10
import com.ai.ipu.nosql.mongodb.MongoCacheFactory;
11

12

13

14
@Aspect
15
public class TransactionAspect {
16
    transient protected ILogger log = IpuLoggerFactory.createLogger(TransactionAspect.class);
17
    final static String executionService = "execution(* com.ai..service..*Impl.process*(..))";
18
    
19
    @Pointcut(executionService)
20
    private void serviceTransaction() {}
21
    
22
    @Around("serviceTransaction()")
23
    public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable {
24
        Object result = null;
25
        try {
26
            result = jp.proceed();           
27
            long start = System.currentTimeMillis();
28
            MongoCacheFactory.commitAll();
29
            log.debug("提交mongo数据库连接耗时:"+(System.currentTimeMillis()-start));
30
        } catch (Exception e) {
31
            log.error(e.getMessage(), e);
32
            log.debug("mongo数据库全量回滚");
33
            MongoCacheFactory.rollbackAll(); 
34
            throw e;
35
        } finally{
36
        	log.debug("mongo数据库切面控制完成");
37
        	MongoCacheFactory.closeAll();
38
        }
39
        return result;
40
    }
41
}

+ 69 - 0
ipu-rest-demo/src/main/resources/dev/ipu-nosql.xml

@ -0,0 +1,69 @@
1
<?xml version = '1.0' encoding = 'UTF-8'?>
2
<connections>
3
    <connection name="data" type="mongo">
4
        <servers>
5
            <server ip="47.105.160.21" port="10030" />
6
            <server ip="47.105.160.21" port="10040" />
7
            <server ip="47.105.160.21" port="10050" />
8
        </servers>
9
        <!-- 连接时数据库名,不做身份验证时可空;身份认证时必填 -->
10
        <config name="authSource" value="test"/>
11
        <!-- 认证机制,不做身份验证时可空;身份认证时必填。mongo3.0及更高版本缺省是SCRAM-SHA-1 -->
12
        <!-- mongo2.6以前缺省是MONGODB-CR, mongo4.0及更高版本已经不再支持-->
13
        <!-- 支持SCRAM-SHA-1、SCRAM-SHA-256-->
14
        <!-- 当前组件不支持x.509证书 -->
15
        <config name="authMechanism" value="SCRAM-SHA-256"/>
16
        <!-- 用户名,不做身份验证时可空;身份认证时必填 -->
17
        <config name="userName" value="ipuOper"/>
18
        <!-- 加密后的用户密码,不做身份验证时可空;身份认证时必填 -->
19
        <!-- 加密算法需要用一对@@包含,并且放在密码的最前面。如果没有发现加密算法,则为明文密码  -->
20
        <config name="encryptedPasswd" value="@DES@L4+tgpw/Q67MvcM4mN1AhQ=="/>
21
        <!-- 解密秘钥 ,可为空 -->
22
        <config name="decryptedKey" value="325m@#$rt4vt"/>
23
        <!-- 自定义解密算法需要在pom.xml里引入所需jar,并在此声明带全包名的类 -->
24
        <config name="decryptedClass" value="com.ai.ipu.nosql.util.DecryptUtil"/>
25
        <!-- 自定义解密算法的解密算法,加密后的秘钥(可为空,为空则只有1个参数)、密码串是算法的2个参数  -->
26
        <config name="decryptedMethod" value="decryptDES"/>
27
        <!-- 是否支持事务,true为支持,其他值为不支持 -->
28
        <config name="needTranscation" value="true"/>
29
        <!-- 复制集名称,可以为空 -->
30
        <config name="replicaSet" value="lpsa_repl"/>
31
        <!-- 客户端最大连接数,超过了将会被阻塞,默认100 -->
32
        <config name="connectionsPerHost" />
33
        <!-- 客户端最小连接数 -->
34
        <config name="minConnectionsPerHost" />
35
        <!-- 可被阻塞的线程数因子,默认值为5,如果connectionsPerHost配置为10, -->
36
        <!-- 那么最多能阻塞50个线程,超过50个之后就会收到一个异常  -->
37
        <config name="threadAllowedToBlockForConnectionMultiplier" />
38
        <!-- 阻塞线程获取连接的最长等待时间,默认120000 ms -->
39
        <config name="maxWaitTime" />
40
        <!-- 连接池连接最大空闲时间,默认为0 -->
41
        <config name="maxConnectionIdleTime" />
42
        <!-- 连接池连接的最大存活时间,默认为0 -->
43
        <config name="maxConnectionLifeTime" />
44
        <!-- 连接超时时间,默认值是0,就是不超时 -->
45
        <config name="connectTimeout" />
46
        <!-- 超时时间,默认值是0,就是不超时 -->
47
        <config name="socketTimeout" />
48
        <!-- 当没有手动关闭游标时,是否自动释放游标对象。默认为 true。-->
49
        <config name="cursorFinalizerEnabled" />
50
        <!-- MongoDB有5种ReadPreference模式 -->
51
        <!-- primary            主节点,默认模式,读操作只在主节点,如果主节点不可用,报错或者抛出异常。-->
52
        <!-- primaryPreferred   首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。-->
53
        <!-- secondary          从节点,读操作只在从节点, 如果从节点不可用,报错或者抛出异常。-->
54
        <!-- secondaryPreferred 首选从节点,大多情况下读操作在从节点,特殊情况(如单主节点架构)读操作在主节点。-->
55
        <!-- nearest            最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点-->
56
        <config name="readPreference" />
57
    </connection>
58
    
59
    <connection name="simple" type="mongo">
60
        <servers>
61
            <server ip="10.1.236.121" port="11000" />
62
            <server ip="10.1.236.121" port="11010" />
63
            <server ip="10.1.236.121" port="11020" />
64
        </servers>
65
        <!-- 复制集名称,可以为空 -->
66
        <config name="replicaSet" value="lpsa_repl"/>
67
    </connection>
68

69
</connections>

+ 1 - 0
ipu-rest-demo/src/main/resources/ipu-spring-mvc.xml

@ -11,4 +11,5 @@
11 11
		http://www.springframework.org/schema/mvc/spring-mvc.xsd">
12 12
	<!-- 自定义的control扫描目录 -->
13 13
    <context:component-scan base-package="com.ai.ipu.server.demo" />
14
    <bean id="transcationAspects" class="com.ipu.server.aspect.TransactionAspect" />
14 15
</beans>