mirror of
https://gitee.com/nutz/nutzboot.git
synced 2024-12-04 20:58:22 +08:00
Merge branch 'dev' of github.com:nutzam/nutzboot into dev
This commit is contained in:
commit
bc85aed144
@ -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
26
nutzboot-demo/nutzboot-demo-dubbo-fescar/pom.xml
Normal file
26
nutzboot-demo/nutzboot-demo-dubbo-fescar/pom.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<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>
|
||||
</modules>
|
||||
<properties>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -34,5 +34,20 @@
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.101tec</groupId>
|
||||
<artifactId>zkclient</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -2,7 +2,6 @@ server.port=8080
|
||||
server.host=0.0.0.0
|
||||
|
||||
dubbo.application.name=dubbo-rpc-client
|
||||
#dubbo.registry.address=multicast://224.5.6.7:1234
|
||||
#dubbo.protocol.name=dubbo
|
||||
#dubbo.protocol.port=20880
|
||||
#dubbo.annotation.package=io.nutz.demo.dubbo.rpc
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
@ -1,4 +1,5 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<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>
|
||||
@ -26,5 +27,19 @@
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.34.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.101tec</groupId>
|
||||
<artifactId>zkclient</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,7 +1,6 @@
|
||||
server.port=0
|
||||
|
||||
dubbo.application.name=dubbo-rpc-service
|
||||
#dubbo.registry.address=multicast://224.5.6.7:1234
|
||||
#dubbo.protocol.name=dubbo
|
||||
#dubbo.protocol.port=20880
|
||||
#dubbo.annotation.package=io.nutz.demo.dubbo.rpc
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.application.qos.enable=false
|
@ -13,6 +13,7 @@
|
||||
<module>nutzboot-demo-dubbo-rpc-service</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<zkclient.version>0.11</zkclient.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -19,6 +19,7 @@
|
||||
<module>nutzboot-demo-cloud</module>
|
||||
<module>nutzboot-demo-servicecomb</module>
|
||||
<module>nutzboot-demo-custom</module>
|
||||
<module>nutzboot-demo-dubbo-fescar</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<docker.image.prefix>nutzboot</docker.image.prefix>
|
||||
|
25
nutzboot-starter/nutzboot-starter-fescar/pom.xml
Normal file
25
nutzboot-starter/nutzboot-starter-fescar/pom.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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-starter</artifactId>
|
||||
<version>2.3.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<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>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
package org.nutz.boot.starter.fescar;
|
||||
|
||||
import com.alibaba.fescar.config.ConfigurationFactory;
|
||||
|
||||
public class FescarHelper {
|
||||
|
||||
public static boolean disableGlobalTransaction = ConfigurationFactory.getInstance().getBoolean("service.disableGlobalTransaction", false);
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package org.nutz.boot.starter.fescar;
|
||||
|
||||
import org.nutz.boot.AppContext;
|
||||
import org.nutz.boot.annotation.PropDoc;
|
||||
import org.nutz.boot.starter.ServerFace;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
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.fescar.common.util.StringUtils;
|
||||
import com.alibaba.fescar.rm.RMClient;
|
||||
import com.alibaba.fescar.tm.TMClient;
|
||||
|
||||
@IocBean
|
||||
public class FescarStarter implements ServerFace {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
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;
|
||||
|
||||
@Inject
|
||||
protected AppContext appContext;
|
||||
|
||||
private String applicationId;
|
||||
private String txServiceGroup;
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
if (FescarHelper.disableGlobalTransaction) {
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Global transaction is disabled.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!conf.getBoolean("fescar.enable", true)) {
|
||||
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();
|
||||
}
|
||||
|
||||
protected void initClient() {
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Initializing Global Transaction Clients ... ");
|
||||
}
|
||||
if (StringUtils.isNullOrEmpty(applicationId) || StringUtils.isNullOrEmpty(txServiceGroup)) {
|
||||
throw new IllegalArgumentException("applicationId: " + applicationId + ", txServiceGroup: " + txServiceGroup);
|
||||
}
|
||||
// init TM
|
||||
TMClient.init(applicationId, txServiceGroup);
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Transaction Manager Client is initialized. applicationId[" + applicationId + "] txServiceGroup[" + txServiceGroup + "]");
|
||||
}
|
||||
// init RM
|
||||
RMClient.init(applicationId, txServiceGroup);
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Resource Manager is initialized. applicationId[" + applicationId + "] txServiceGroup[" + txServiceGroup + "]");
|
||||
}
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Global Transaction Clients are initialized. ");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.nutz.boot.starter.fescar.aop.lock;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.nutz.aop.MethodInterceptor;
|
||||
import org.nutz.boot.starter.fescar.FescarHelper;
|
||||
import org.nutz.ioc.Ioc;
|
||||
import org.nutz.ioc.aop.SimpleAopMaker;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import com.alibaba.fescar.spring.annotation.GlobalLock;
|
||||
|
||||
@IocBean(name = "$aop_fescar_GlobalLock")
|
||||
public class FescarLockAopMaker extends SimpleAopMaker<GlobalLock> {
|
||||
|
||||
public List<? extends MethodInterceptor> makeIt(GlobalLock t, Method method, Ioc ioc) {
|
||||
if (FescarHelper.disableGlobalTransaction)
|
||||
return null;
|
||||
return Arrays.asList(new FescarLockInterceptor());
|
||||
}
|
||||
|
||||
public String[] getName() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public boolean has(String name) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package org.nutz.boot.starter.fescar.aop.lock;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.nutz.aop.InterceptorChain;
|
||||
import org.nutz.aop.MethodInterceptor;
|
||||
|
||||
import com.alibaba.fescar.rm.GlobalLockTemplate;
|
||||
|
||||
/**
|
||||
* 全局锁
|
||||
* @author wendal
|
||||
*
|
||||
*/
|
||||
public class FescarLockInterceptor implements MethodInterceptor {
|
||||
|
||||
private GlobalLockTemplate<Object> globalLockTemplate = new GlobalLockTemplate<>();
|
||||
|
||||
public void filter(InterceptorChain chain) throws Throwable {
|
||||
globalLockTemplate.execute(new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
try {
|
||||
return chain.doChain().getReturn();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (e instanceof Exception) {
|
||||
throw (Exception) e;
|
||||
} else {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.nutz.boot.starter.fescar.aop.trans;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.nutz.aop.MethodInterceptor;
|
||||
import org.nutz.boot.starter.fescar.FescarHelper;
|
||||
import org.nutz.ioc.Ioc;
|
||||
import org.nutz.ioc.aop.SimpleAopMaker;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
|
||||
import com.alibaba.fescar.tm.api.DefaultFailureHandlerImpl;
|
||||
import com.alibaba.fescar.tm.api.FailureHandler;
|
||||
|
||||
@IocBean(name="$aop_fescar_GlobalTransactional")
|
||||
public class FescarTransAopMaker extends SimpleAopMaker<GlobalTransactional> {
|
||||
|
||||
private static FailureHandler DFT = new DefaultFailureHandlerImpl();
|
||||
|
||||
public List<? extends MethodInterceptor> makeIt(GlobalTransactional t, Method method, Ioc ioc) {
|
||||
if (FescarHelper.disableGlobalTransaction)
|
||||
return null;
|
||||
FailureHandler failureHandler = DFT;
|
||||
if (ioc.has("fescarFailureHandler")) {
|
||||
failureHandler = ioc.get(FailureHandler.class, "fescarFailureHandler");
|
||||
}
|
||||
return Arrays.asList(new FescarTransInterceptor(failureHandler, t, method));
|
||||
}
|
||||
|
||||
public String[] getName() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public boolean has(String name) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.nutz.boot.starter.fescar.aop.trans;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.nutz.aop.InterceptorChain;
|
||||
import org.nutz.aop.MethodInterceptor;
|
||||
import org.nutz.lang.Lang;
|
||||
|
||||
import com.alibaba.fescar.common.exception.ShouldNeverHappenException;
|
||||
import com.alibaba.fescar.common.util.StringUtils;
|
||||
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
|
||||
import com.alibaba.fescar.tm.api.DefaultFailureHandlerImpl;
|
||||
import com.alibaba.fescar.tm.api.FailureHandler;
|
||||
import com.alibaba.fescar.tm.api.TransactionalExecutor;
|
||||
import com.alibaba.fescar.tm.api.TransactionalTemplate;
|
||||
|
||||
/**
|
||||
* The type Global transactional interceptor. 全局事务拦截器
|
||||
*/
|
||||
public class FescarTransInterceptor implements MethodInterceptor {
|
||||
|
||||
private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
|
||||
|
||||
private final TransactionalTemplate transactionalTemplate = new TransactionalTemplate();
|
||||
private final FailureHandler failureHandler;
|
||||
private GlobalTransactional globalTrxAnno;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Instantiates a new Global transactional interceptor.
|
||||
*
|
||||
* @param failureHandler the failure handler
|
||||
*/
|
||||
public FescarTransInterceptor(FailureHandler failureHandler, GlobalTransactional globalTrxAnno, Method method) {
|
||||
if (null == failureHandler) {
|
||||
failureHandler = DEFAULT_FAIL_HANDLER;
|
||||
}
|
||||
this.failureHandler = failureHandler;
|
||||
this.globalTrxAnno = globalTrxAnno;
|
||||
String name = globalTrxAnno.name();
|
||||
if (!StringUtils.isNullOrEmpty(name)) {
|
||||
this.name = name;
|
||||
}
|
||||
else
|
||||
this.name = Lang.simpleMethodDesc(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(InterceptorChain chain) throws Throwable {
|
||||
try {
|
||||
transactionalTemplate.execute(new TransactionalExecutor() {
|
||||
@Override
|
||||
public Object execute() throws Throwable {
|
||||
return chain.doChain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int timeout() {
|
||||
return globalTrxAnno.timeoutMills();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
} catch (TransactionalExecutor.ExecutionException e) {
|
||||
TransactionalExecutor.Code code = e.getCode();
|
||||
switch (code) {
|
||||
case RollbackDone:
|
||||
throw e.getOriginalException();
|
||||
case BeginFailure:
|
||||
failureHandler.onBeginFailure(e.getTransaction(), e.getCause());
|
||||
throw e.getCause();
|
||||
case CommitFailure:
|
||||
failureHandler.onCommitFailure(e.getTransaction(), e.getCause());
|
||||
throw e.getCause();
|
||||
case RollbackFailure:
|
||||
failureHandler.onRollbackFailure(e.getTransaction(), e.getCause());
|
||||
throw e.getCause();
|
||||
default:
|
||||
throw new ShouldNeverHappenException("Unknown TransactionalExecutor.Code: " + code);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package org.nutz.boot.starter.fescar.datasource;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.nutz.boot.starter.fescar.FescarHelper;
|
||||
import org.nutz.boot.starter.fescar.FescarStarter;
|
||||
import org.nutz.ioc.IocEventListener;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
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.druid.pool.DruidDataSource;
|
||||
import com.alibaba.fescar.rm.datasource.DataSourceManager;
|
||||
import com.alibaba.fescar.rm.datasource.DataSourceProxy;
|
||||
|
||||
@IocBean
|
||||
public class FescarDataSourceHandler implements IocEventListener {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
@Inject
|
||||
protected PropertiesProxy conf;
|
||||
|
||||
public Object afterBorn(Object obj, String beanName) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Object afterCreate(Object obj, String beanName) {
|
||||
if (obj == null)
|
||||
return null;
|
||||
if (obj instanceof DruidDataSource) {
|
||||
if (FescarHelper.disableGlobalTransaction) {
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Global transaction is disabled.");
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
log.info("proxy DruidDataSource : " + obj.hashCode());
|
||||
DruidDataSource ds = (DruidDataSource)obj;
|
||||
DataSourceProxy proxy = new DataSourceProxy(ds, "DEFAULT");
|
||||
DataSourceManager.get().registerResource(proxy);
|
||||
if (conf.getBoolean(FescarStarter.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();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
log.warn("fail to create fescar's undo_log table", e);
|
||||
}
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
org.nutz.boot.starter.fescar.FescarStarter
|
@ -0,0 +1,45 @@
|
||||
# 阿里开源项目 Sentinel: 分布式系统的流量防卫兵 dubbo适配
|
||||
|
||||
nutzboot-starter-sentinel-dubbo
|
||||
|
||||
## 控制台启动
|
||||
|
||||
* https://github.com/alibaba/Sentinel/releases
|
||||
|
||||
```
|
||||
java -Dserver.port=9090 -Dcsp.sentinel.dashboard.server=localhost:9090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.4.1.jar
|
||||
```
|
||||
|
||||
## 客户端配置
|
||||
```
|
||||
#是否启用sentinel客户端
|
||||
sentinel.enabled=true
|
||||
#控制台地址
|
||||
sentinel.csp.sentinel.dashboard.server=localhost:9090
|
||||
#sentinel客户端端口
|
||||
sentinel.csp.sentinel.api.port=8721
|
||||
#sentinel客户端通信间隔毫秒数
|
||||
sentinel.csp.sentinel.heartbeat.interval.ms=3000
|
||||
#sentinel客户端本地IP地址,不设置则自动获取
|
||||
sentinel.csp.sentinel.heartbeat.client.ip=
|
||||
|
||||
#规则存储的key名
|
||||
sentinel.rulekey=nutzboot
|
||||
#规则存储的发布订阅频道名
|
||||
sentinel.channel=sentinel
|
||||
|
||||
#redis配置内容,用于存储规则,sentinel.enabled=true时初始化加载
|
||||
redis.host=127.0.0.1
|
||||
redis.port=6379
|
||||
redis.timeout=2000
|
||||
redis.max_redir=10
|
||||
redis.database=0
|
||||
redis.maxTotal=100
|
||||
redis.pool.maxTotal=100
|
||||
redis.pool.maxIdle=50
|
||||
redis.pool.minIdle=10
|
||||
#redis.password=test123
|
||||
#redis集群模式设置 redis.mode=cluster
|
||||
redis.mode=normal
|
||||
#redis.nodes=
|
||||
```
|
@ -75,6 +75,7 @@
|
||||
<module>nutzboot-starter-nacos-config-client</module>
|
||||
<module>nutzboot-starter-ftp</module>
|
||||
<module>nutzboot-starter-fastdfs</module>
|
||||
<module>nutzboot-starter-fescar</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
6
pom.xml
6
pom.xml
@ -46,6 +46,7 @@
|
||||
<javassist.version>3.24.0-GA</javassist.version>
|
||||
<fastdfs-client-java.version>1.29.4</fastdfs-client-java.version>
|
||||
<commons-pool2.version>2.6.1</commons-pool2.version>
|
||||
<fescar.version>0.4.0</fescar.version>
|
||||
</properties>
|
||||
<description>NutzBoot, micoservice base on Nutz</description>
|
||||
|
||||
@ -929,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