mirror of
https://gitee.com/nutz/nutzboot.git
synced 2024-11-29 18:28:01 +08:00
add: 完成经过验证的fescar集成及配套的demo
This commit is contained in:
parent
93957c7e6d
commit
7236f848f4
@ -210,8 +210,9 @@ public class MainLauncher {
|
||||
- [x] [Shiro+LCache](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-cache)基于shiro/jedis/插件的分布式可持久化的session缓存
|
||||
- 分布式事务
|
||||
- [x] [tcc-transaction](https://github.com/changmingxie/tcc-transaction/tree/dev-1.2.x)基于tcc-transaction的nutz容器支持
|
||||
- [x] [fescar](https://github.com/alibaba/fescar) 阿里开源的分布式事务引擎
|
||||
- 计划任务
|
||||
- [x] **starter-[quartz](http://www.quartz-scheduler.org)**
|
||||
- [x] **starter-[quartz](http://www.quartz-scheduler.org)** 大家都知道
|
||||
- [x] starter-xxl-job [国产分布式任务调度平台](https://github.com/xuxueli/xxl-job/pull/253)
|
||||
- [ ] starter-scheduledx 阿里云分布式任务
|
||||
- 模板引擎
|
||||
|
@ -0,0 +1,47 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-account</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-dao</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-dubbo-alibaba</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,31 @@
|
||||
package io.nutz.demo.dubbo.rpc;
|
||||
|
||||
import org.nutz.boot.NbApp;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import io.nutz.demo.bean.Account;
|
||||
|
||||
@IocBean(create="init")
|
||||
public class DemoFescarAccountServiceLauncher {
|
||||
|
||||
@Inject
|
||||
Dao dao;
|
||||
|
||||
public void init() {
|
||||
dao.create(Account.class, false);
|
||||
if (dao.count(Account.class, Cnd.where("userId", "=", "U100001")) == 0) {
|
||||
Account account = new Account();
|
||||
account.setUserId("U100001");
|
||||
account.setMoney(1000);
|
||||
dao.insert(account);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NbApp().run();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package io.nutz.demo.dubbo.rpc.service.impl;
|
||||
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
import com.alibaba.fescar.core.context.RootContext;
|
||||
|
||||
import io.nutz.demo.bean.Account;
|
||||
import io.nutz.demo.dubbo.rpc.service.AccountService;
|
||||
|
||||
@IocBean
|
||||
@Service(interfaceClass=AccountService.class)
|
||||
public class AccountServiceImpl implements AccountService {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@Override
|
||||
public void debit(String userId, int money) {
|
||||
log.info("Account Service ... xid: " + RootContext.getXID());
|
||||
log.infof("Deducting balance SQL: update account_tbl set money = money - %s where user_id = %s", money, userId);
|
||||
|
||||
dao.update(Account.class, Chain.makeSpecial("money", "-" + money), Cnd.where("userId", "=", userId));
|
||||
log.info("Account Service End ... ");
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
transport {
|
||||
# tcp udt unix-domain-socket
|
||||
type = "TCP"
|
||||
#NIO NATIVE
|
||||
server = "NIO"
|
||||
#enable heartbeat
|
||||
heartbeat = true
|
||||
#thread factory for netty
|
||||
thread-factory {
|
||||
boss-thread-prefix = "NettyBoss"
|
||||
worker-thread-prefix = "NettyServerNIOWorker"
|
||||
server-executor-thread-prefix = "NettyServerBizHandler"
|
||||
share-boss-worker = false
|
||||
client-selector-thread-prefix = "NettyClientSelector"
|
||||
client-selector-thread-size = 1
|
||||
client-worker-thread-prefix = "NettyClientWorkerThread"
|
||||
# netty boss thread size,will not be used for UDT
|
||||
boss-thread-size = 1
|
||||
#auto default pin or 8
|
||||
worker-thread-size = 8
|
||||
}
|
||||
}
|
||||
service {
|
||||
#vgroup->rgroup
|
||||
vgroup_mapping.my_test_tx_group = "localRgroup"
|
||||
#only support single node
|
||||
localRgroup.grouplist = "127.0.0.1:8091"
|
||||
#degrade current not support
|
||||
enableDegrade = false
|
||||
#disable
|
||||
disable = false
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
server.port=0
|
||||
|
||||
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
|
||||
jdbc.username=root
|
||||
jdbc.password=root
|
||||
fescar.applicationId=dubbo-fescar-account
|
||||
fescar.txServiceGroup=my_test_tx_group
|
||||
|
||||
dubbo.application.name=dubbo-fescar-account
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
@ -0,0 +1,7 @@
|
||||
log4j.rootLogger=debug,Console
|
||||
|
||||
log4j.logger.org.eclipse.jetty=info
|
||||
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n
|
@ -0,0 +1,27 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-dubbo</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,47 @@
|
||||
package io.nutz.demo.bean;
|
||||
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Index;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.entity.annotation.TableIndexes;
|
||||
|
||||
@Table("account_tbl")
|
||||
@TableIndexes(@Index(fields="userId", unique=true))
|
||||
public class Account {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
@Column("user_id")
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
private int money;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public int getMoney() {
|
||||
return money;
|
||||
}
|
||||
|
||||
public void setMoney(int money) {
|
||||
this.money = money;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package io.nutz.demo.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
|
||||
@Table("order_tbl")
|
||||
public class Order implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private long id;
|
||||
@Column("user_id")
|
||||
private String userId;
|
||||
@Column("commodity_code")
|
||||
private String commodityCode;
|
||||
@Column
|
||||
private int count;
|
||||
@Column
|
||||
private int money;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
public String getCommodityCode() {
|
||||
return commodityCode;
|
||||
}
|
||||
public void setCommodityCode(String commodityCode) {
|
||||
this.commodityCode = commodityCode;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
public int getMoney() {
|
||||
return money;
|
||||
}
|
||||
public void setMoney(int money) {
|
||||
this.money = money;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package io.nutz.demo.bean;
|
||||
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
|
||||
@Table("storage_tbl")
|
||||
public class Storage {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
@Column("commodity_code")
|
||||
private String commodityCode;
|
||||
@Column
|
||||
private int count;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCommodityCode() {
|
||||
return commodityCode;
|
||||
}
|
||||
|
||||
public void setCommodityCode(String commodityCode) {
|
||||
this.commodityCode = commodityCode;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package io.nutz.demo.dubbo.rpc.service;
|
||||
public interface AccountService {
|
||||
|
||||
/**
|
||||
* debit balance of user's account
|
||||
*/
|
||||
void debit(String userId, int money);
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package io.nutz.demo.dubbo.rpc.service;
|
||||
|
||||
public interface BusinessService {
|
||||
|
||||
void purchase(String userId, String commodityCode, int orderCount, boolean dofail);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.nutz.demo.dubbo.rpc.service;
|
||||
|
||||
import io.nutz.demo.bean.Order;
|
||||
|
||||
public interface OrderService {
|
||||
|
||||
/**
|
||||
* create order
|
||||
*/
|
||||
Order create(String userId, String commodityCode, int orderCount);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package io.nutz.demo.dubbo.rpc.service;
|
||||
public interface StorageService {
|
||||
|
||||
/**
|
||||
* deduct storage count
|
||||
*/
|
||||
void deduct(String commodityCode, int count);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-order</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-dao</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-dubbo-alibaba</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,23 @@
|
||||
package io.nutz.demo.dubbo.rpc;
|
||||
|
||||
import org.nutz.boot.NbApp;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import io.nutz.demo.bean.Order;
|
||||
|
||||
@IocBean(create="init")
|
||||
public class DemoFescarOrderServiceLauncher {
|
||||
|
||||
@Inject Dao dao;
|
||||
|
||||
public void init() {
|
||||
dao.create(Order.class, false);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NbApp().run();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package io.nutz.demo.dubbo.rpc.service.impl;
|
||||
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
|
||||
import io.nutz.demo.bean.Order;
|
||||
import io.nutz.demo.dubbo.rpc.service.AccountService;
|
||||
import io.nutz.demo.dubbo.rpc.service.OrderService;
|
||||
|
||||
@IocBean
|
||||
@Service(interfaceClass=OrderService.class)
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@Inject
|
||||
@Reference
|
||||
private AccountService accountService;
|
||||
|
||||
public Order create(String userId, String commodityCode, int orderCount) {
|
||||
|
||||
int orderMoney = calculate(commodityCode, orderCount);
|
||||
|
||||
accountService.debit(userId, orderMoney);
|
||||
|
||||
Order order = new Order();
|
||||
order.setUserId(userId);
|
||||
order.setCommodityCode(commodityCode);
|
||||
order.setCount(orderCount);
|
||||
order.setMoney(orderMoney);
|
||||
|
||||
// INSERT INTO orders ...
|
||||
return dao.insert(order);
|
||||
}
|
||||
|
||||
protected int calculate(String commodityCode, int orderCount) {
|
||||
return 100;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
server.port=0
|
||||
|
||||
dubbo.application.name=dubbo-fescar-order
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
||||
|
||||
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
|
||||
jdbc.username=root
|
||||
jdbc.password=root
|
||||
|
||||
fescar.applicationId=dubbo-fescar-order
|
||||
fescar.txServiceGroup=my_test_tx_group
|
@ -0,0 +1,7 @@
|
||||
log4j.rootLogger=debug,Console
|
||||
|
||||
log4j.logger.org.eclipse.jetty=info
|
||||
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n
|
@ -0,0 +1,47 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-storage</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-dubbo-alibaba</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-dao</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,30 @@
|
||||
package io.nutz.demo.dubbo.rpc;
|
||||
|
||||
import org.nutz.boot.NbApp;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import io.nutz.demo.bean.Storage;
|
||||
|
||||
@IocBean(create="init")
|
||||
public class DemoFescarStorageServiceLauncher {
|
||||
|
||||
@Inject Dao dao;
|
||||
|
||||
public void init() {
|
||||
dao.create(Storage.class, false);
|
||||
if (dao.count(Storage.class, Cnd.where("commodityCode", "=", "C00321")) == 0) {
|
||||
Storage storage = new Storage();
|
||||
storage.setCommodityCode("C00321");
|
||||
storage.setCount(100);
|
||||
dao.insert(storage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NbApp().run();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package io.nutz.demo.dubbo.rpc.service.impl;
|
||||
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Service;
|
||||
import com.alibaba.fescar.core.context.RootContext;
|
||||
|
||||
import io.nutz.demo.bean.Storage;
|
||||
import io.nutz.demo.dubbo.rpc.service.StorageService;
|
||||
|
||||
@IocBean
|
||||
@Service(interfaceClass=StorageService.class)
|
||||
public class StorageServiceImpl implements StorageService {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@Override
|
||||
public void deduct(String commodityCode, int count) {
|
||||
log.info("Storage Service Begin ... xid: " + RootContext.getXID());
|
||||
log.infof("Deducting inventory SQL: update storage_tbl set count = count - %s where commodity_code = %s", count, commodityCode);
|
||||
|
||||
dao.update(Storage.class, Chain.makeSpecial("count", "-" + count), Cnd.where("commodityCode", "=", commodityCode));
|
||||
log.info("Storage Service End ... ");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
server.port=0
|
||||
|
||||
dubbo.application.name=dubbo-fescar-storage
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
||||
|
||||
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
|
||||
jdbc.username=root
|
||||
jdbc.password=root
|
||||
|
||||
|
||||
fescar.applicationId=dubbo-fescar-storage
|
||||
fescar.txServiceGroup=my_test_tx_group
|
@ -0,0 +1,7 @@
|
||||
log4j.rootLogger=debug,Console
|
||||
|
||||
log4j.logger.org.eclipse.jetty=info
|
||||
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n
|
@ -0,0 +1,55 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-web</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-mvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-dubbo-alibaba</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-dao</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,67 @@
|
||||
package io.nutz.demo.dubbo.rpc;
|
||||
|
||||
import org.nutz.boot.NbApp;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import io.nutz.demo.bean.Account;
|
||||
import io.nutz.demo.bean.Storage;
|
||||
import io.nutz.demo.dubbo.rpc.service.BusinessService;
|
||||
|
||||
@IocBean
|
||||
public class DemoFescarWebLauncher {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
@Inject
|
||||
protected BusinessService businessService;
|
||||
|
||||
// 订购信息
|
||||
@Ok("json:full")
|
||||
@At("/api/purchase")
|
||||
public NutMap purchase(String userId, String commodityCode, int orderCount, boolean dofail) {
|
||||
try {
|
||||
businessService.purchase(userId, commodityCode, orderCount, dofail);
|
||||
return new NutMap("ok", true);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
log.debug("purchase fail", e);
|
||||
return new NutMap("ok", false);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
@Inject
|
||||
protected Dao dao;
|
||||
|
||||
// 用于页面显示数据
|
||||
@Ok("json:full")
|
||||
@At("/api/info")
|
||||
public NutMap info() {
|
||||
NutMap re = new NutMap();
|
||||
NutMap data = new NutMap();
|
||||
data.put("account", dao.fetch(Account.class, Cnd.where("userId", "=", "U100001")));
|
||||
data.put("storage", dao.fetch(Storage.class, Cnd.where("commodityCode", "=", "C00321")));
|
||||
return re.setv("data", data).setv("ok", true);
|
||||
}
|
||||
|
||||
// 要启动zk做dubbo注册服务, fescar-server也需要下载启动
|
||||
// 数据库名称 fescar_demo, 用户名密码均为root,可以在application.properties里面修改
|
||||
//启动顺序: account,storage,order,web, 服务启动完成后再启动下一个
|
||||
// 页面操作: http://127.0.0.1:8080/
|
||||
//正常操作:
|
||||
// http://127.0.0.1:8080/api/purchase?userId=U100001&commodityCode=C00321&orderCount=1
|
||||
// 故意抛出异常:
|
||||
// http://127.0.0.1:8080/api/purchase?userId=U100001&commodityCode=C00321&orderCount=1&dofail=true
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NbApp().run();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package io.nutz.demo.dubbo.rpc.service.impl;
|
||||
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import com.alibaba.fescar.core.context.RootContext;
|
||||
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
|
||||
|
||||
import io.nutz.demo.dubbo.rpc.service.BusinessService;
|
||||
import io.nutz.demo.dubbo.rpc.service.OrderService;
|
||||
import io.nutz.demo.dubbo.rpc.service.StorageService;
|
||||
|
||||
@IocBean
|
||||
public class BusinessServiceImpl implements BusinessService {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
@Inject
|
||||
@Reference
|
||||
private StorageService storageService;
|
||||
|
||||
|
||||
@Inject
|
||||
@Reference
|
||||
private OrderService orderService;
|
||||
|
||||
/**
|
||||
* purchase
|
||||
*/
|
||||
@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")
|
||||
public void purchase(String userId, String commodityCode, int orderCount, boolean dofail) {
|
||||
log.info("purchase begin ... xid: " + RootContext.getXID());
|
||||
|
||||
storageService.deduct(commodityCode, orderCount);
|
||||
orderService.create(userId, commodityCode, orderCount);
|
||||
|
||||
// for test
|
||||
if (dofail)
|
||||
throw new RuntimeException("just make it failed");
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
server.port=8080
|
||||
server.host=0.0.0.0
|
||||
|
||||
dubbo.application.name=dubbo-fescar-web
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
||||
|
||||
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
|
||||
jdbc.username=root
|
||||
jdbc.password=root
|
||||
|
||||
fescar.applicationId=dubbo-fescar-web
|
||||
fescar.txServiceGroup=my_test_tx_group
|
@ -0,0 +1,7 @@
|
||||
log4j.rootLogger=debug,Console
|
||||
|
||||
log4j.logger.org.eclipse.jetty=info
|
||||
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n
|
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Fescar分布式事务演示</title>
|
||||
<script type="text/javascript" src="vue.js"></script>
|
||||
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div>
|
||||
<span>当前余额: </span><input v-model="account_money" disabled="disabled">
|
||||
</div>
|
||||
<div>
|
||||
<span>剩余库存: </span><input v-model="storage_count" disabled="disabled">
|
||||
</div>
|
||||
<div>
|
||||
<button @click="buyit(false)">购买并成功</button>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="buyit(true)">购买但失败</button>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="dataReload">刷新</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
var _app = new Vue({
|
||||
el : "#app",
|
||||
data : {
|
||||
account_money : 0,
|
||||
storage_count : 0
|
||||
},
|
||||
methods : {
|
||||
dataReload : function() {
|
||||
$.ajax({
|
||||
url : "api/info",
|
||||
success : function(re) {
|
||||
if (re && re.ok) {
|
||||
_app.account_money = re.data.account.money;
|
||||
_app.storage_count = re.data.storage.count;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
buyit : function(dofail) {
|
||||
$.ajax({
|
||||
url : "api/purchase?userId=U100001&commodityCode=C00321&orderCount=1&dofail=" + dofail,
|
||||
success : function(re) {
|
||||
if (re && re.ok) {
|
||||
alert("真的是购买成功");
|
||||
}
|
||||
else {
|
||||
alert("真的是购买失败");
|
||||
}
|
||||
_app.dataReload();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
_app.dataReload();
|
||||
</script>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
27
nutzboot-demo/nutzboot-demo-dubbo-fescar/pom.xml
Normal file
27
nutzboot-demo/nutzboot-demo-dubbo-fescar/pom.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>nutzboot-demo-dubbo-fescar-common</module>
|
||||
<module>nutzboot-demo-dubbo-fescar-web</module>
|
||||
<module>nutzboot-demo-dubbo-fescar-order</module>
|
||||
<module>nutzboot-demo-dubbo-fescar-account</module>
|
||||
<module>nutzboot-demo-dubbo-fescar-storage</module>
|
||||
<module>nutzboot-demo-dubbo-fescar-business</module>
|
||||
</modules>
|
||||
<properties>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -11,15 +11,15 @@
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
<name>nutzboot-starter-fescar</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-rm-datasource</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-spring</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-rm-datasource</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fescar</groupId>
|
||||
<artifactId>fescar-spring</artifactId>
|
||||
<version>${fescar.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,8 +1,12 @@
|
||||
package org.nutz.boot.starter.fescar;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.nutz.boot.AppContext;
|
||||
import org.nutz.boot.annotation.PropDoc;
|
||||
import org.nutz.boot.starter.ServerFace;
|
||||
import org.nutz.dao.impl.NutDao;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
@ -26,6 +30,15 @@ public class FescarStarter implements ServerFace {
|
||||
|
||||
protected static final String PRE = "fescar.";
|
||||
|
||||
@PropDoc(value="fescar应用id", need=true)
|
||||
public static String PROP_APPID = PRE + "applicationId";
|
||||
|
||||
@PropDoc(value="fescar事务组", need=true)
|
||||
public static String PROP_TXGROUP = PRE + "txServiceGroup";
|
||||
|
||||
@PropDoc(value="自动创建undo表", defaultValue="true")
|
||||
public static String PROP_CREATE_UNDO = PRE + "create_undo_table";
|
||||
|
||||
@Inject
|
||||
protected PropertiesProxy conf;
|
||||
|
||||
@ -49,6 +62,9 @@ public class FescarStarter implements ServerFace {
|
||||
log.info("Global transaction is disabled.");
|
||||
return;
|
||||
}
|
||||
applicationId = conf.check(PROP_APPID);
|
||||
txServiceGroup = conf.check(PROP_TXGROUP);
|
||||
log.infof("fescar applicationId=%s txServiceGroup=%s", applicationId, txServiceGroup);
|
||||
|
||||
initClient();
|
||||
|
||||
@ -57,12 +73,30 @@ public class FescarStarter implements ServerFace {
|
||||
log.error("only DruidDataSource is support by fescar!!!");
|
||||
throw new RuntimeException("only DruidDataSource is support by fescar!!!");
|
||||
}
|
||||
if (conf.getBoolean(PROP_CREATE_UNDO, true)) {
|
||||
try (Connection conn = ds.getConnection()) {
|
||||
Statement st = conn.createStatement();
|
||||
st.execute("CREATE TABLE IF NOT EXISTS " + "`undo_log` (\r\n" +
|
||||
" `id` bigint(20) NOT NULL AUTO_INCREMENT,\r\n" +
|
||||
" `branch_id` bigint(20) NOT NULL,\r\n" +
|
||||
" `xid` varchar(100) NOT NULL,\r\n" +
|
||||
" `rollback_info` longblob NOT NULL,\r\n" +
|
||||
" `log_status` int(11) NOT NULL,\r\n" +
|
||||
" `log_created` datetime NOT NULL,\r\n" +
|
||||
" `log_modified` datetime NOT NULL,\r\n" +
|
||||
" `ext` varchar(100) DEFAULT NULL,\r\n" +
|
||||
" PRIMARY KEY (`id`),\r\n" +
|
||||
" UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)\r\n" +
|
||||
") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8");
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
DataSourceProxy proxy = new DataSourceProxy((DruidDataSource) ds, "DEFAULT");
|
||||
DataSourceManager.get().registerResource(proxy);
|
||||
if (appContext.getIoc().has("dao")) {
|
||||
log.info("looking for NutDao instance and replace DataSource");
|
||||
NutDao dao = appContext.getIoc().get(NutDao.class, "dao");
|
||||
dao.setDataSource(ds);
|
||||
dao.setDataSource(proxy);
|
||||
}
|
||||
else {
|
||||
log.info("NutDao instance not found, skip it");
|
||||
|
@ -12,7 +12,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import com.alibaba.fescar.spring.annotation.GlobalLock;
|
||||
|
||||
@IocBean
|
||||
@IocBean(name = "$aop_fescar_GlobalLock")
|
||||
public class FescarLockAopMaker extends SimpleAopMaker<GlobalLock> {
|
||||
|
||||
public List<? extends MethodInterceptor> makeIt(GlobalLock t, Method method, Ioc ioc) {
|
||||
@ -24,7 +24,7 @@ public class FescarLockAopMaker extends SimpleAopMaker<GlobalLock> {
|
||||
public String[] getName() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
|
||||
public boolean has(String name) {
|
||||
return false;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import com.alibaba.fescar.spring.annotation.GlobalTransactional;
|
||||
import com.alibaba.fescar.tm.api.DefaultFailureHandlerImpl;
|
||||
import com.alibaba.fescar.tm.api.FailureHandler;
|
||||
|
||||
@IocBean
|
||||
@IocBean(name="$aop_fescar_GlobalTransactional")
|
||||
public class FescarTransAopMaker extends SimpleAopMaker<GlobalTransactional> {
|
||||
|
||||
private static FailureHandler DFT = new DefaultFailureHandlerImpl();
|
||||
|
5
pom.xml
5
pom.xml
@ -930,6 +930,11 @@
|
||||
<artifactId>nutzboot-starter-servicecomb</artifactId>
|
||||
<version>${nutzboot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-fescar</artifactId>
|
||||
<version>${nutzboot.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<repositories>
|
||||
|
Loading…
Reference in New Issue
Block a user