io.seata.core.context.RootContext Java Examples

The following examples show how to use io.seata.core.context.RootContext. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PayServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 事务传播特性设置为 REQUIRES_NEW 开启新的事务
 *
 * @param userId 用户 ID
 * @param price  扣减金额
 * @return
 * @throws Exception
 */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@Override
public boolean reduceBalance(Long userId, Integer price) throws Exception {
    log.info("=============PAY=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.PAY);
    log.info("当前 XID: {}", RootContext.getXID());

    checkBalance(userId, price);

    log.info("开始扣减用户 {} 余额", userId);
    Account account = accountDao.selectById(userId);

    account.setBalance(account.getBalance() - price);
    Integer record = accountDao.updateById(account);
    log.info("扣减用户 {} 余额结果:{}", userId, record > 0 ? "操作成功" : "扣减余额失败");

    return record > 0;

}
 
Example #2
Source File: StorageServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 事务传播特性设置为 REQUIRES_NEW 开启新的事务
 *
 * @param productId 商品 ID
 * @param amount    扣减数量
 * @return
 * @throws Exception
 */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@Override
public boolean reduceStock(Long productId, Integer amount) throws Exception {
    log.info("=============STORAGE=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.STORAGE);
    log.info("当前 XID: {}", RootContext.getXID());

    // 检查库存
    checkStock(productId, amount);

    log.info("开始扣减 {} 库存", productId);
    // 扣减库存
    Product product = productDao.selectById(productId);
    product.setStock(product.getStock() - amount);
    Integer record = productDao.updateById(product);
    log.info("扣减 {} 库存结果:{}", productId, record > 0 ? "操作成功" : "扣减库存失败");

    return record > 0;

}
 
Example #3
Source File: OrderService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
public void create(String userId, String commodityCode, Integer count) {
    String xid = RootContext.getXID();
    LOGGER.info("create order in transaction: " + xid);

    // 定单总价 = 订购数量(count) * 商品单价(100)
    int orderMoney = count * 100;
    // 生成订单
    jdbcTemplate.update("insert order_tbl(user_id,commodity_code,count,money) values(?,?,?,?)",
        new Object[] {userId, commodityCode, count, orderMoney});
    // 调用账户余额扣减
    String result = accountFeignClient.reduce(userId, orderMoney);
    if (!SUCCESS.equals(result)) {
        throw new RuntimeException("Failed to call Account Service. ");
    }

}
 
Example #4
Source File: StorageServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 事务传播特性设置为 REQUIRES_NEW 开启新的事务
 *
 * @param productId 商品 ID
 * @param amount    扣减数量
 * @return
 * @throws Exception
 */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@Override
public boolean reduceStock(Long productId, Integer amount) throws Exception {
    log.info("=============STORAGE=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.STORAGE);
    log.info("当前 XID: {}", RootContext.getXID());

    // 检查库存
    checkStock(productId, amount);

    log.info("开始扣减 {} 库存", productId);
    // 扣减库存
    Integer record = productDao.reduceStock(productId, amount);
    log.info("扣减 {} 库存结果:{}", productId, record > 0 ? "操作成功" : "扣减库存失败");

    return record > 0;

}
 
Example #5
Source File: BusinessService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
@GlobalTransactional
public void purchase(String userId, String commodityCode, int orderCount, boolean rollback) {
    String xid = RootContext.getXID();
    LOGGER.info("New Transaction Begins: " + xid);

    String result = storageFeignClient.deduct(commodityCode, orderCount);

    if (!SUCCESS.equals(result)) {
        throw new RuntimeException("库存服务调用失败,事务回滚!");
    }

    result = orderFeignClient.create(userId, commodityCode, orderCount);

    if (!SUCCESS.equals(result)) {
        throw new RuntimeException("订单服务调用失败,事务回滚!");
    }

    if (rollback) {
        throw new RuntimeException("Force rollback ... ");
    }
}
 
Example #6
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 发起分布式事务
 *
 * @return string string
 */
@GlobalTransactional
public String doTransactionCommit(){
    //第一个TCC 事务参与者
    boolean result = tccActionOne.prepare(null, 1);
    if(!result){
        throw new RuntimeException("TccActionOne failed.");
    }
    List list = new ArrayList();
    list.add("c1");
    list.add("c2");
    result = tccActionTwo.prepare(null, "two", list);
    if(!result){
        throw new RuntimeException("TccActionTwo failed.");
    }
    return RootContext.getXID();
}
 
Example #7
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * Do transaction rollback string.
 *
 * @param map the map
 * @return the string
 */
@GlobalTransactional
public String doTransactionRollback(Map map){
    //第一个TCC 事务参与者
    boolean result = tccActionOne.prepare(null, 1);
    if(!result){
        throw new RuntimeException("TccActionOne failed.");
    }
    List list = new ArrayList();
    list.add("c1");
    list.add("c2");
    result = tccActionTwo.prepare(null, "two", list);
    if(!result){
        throw new RuntimeException("TccActionTwo failed.");
    }
    map.put("xid", RootContext.getXID());
    throw new RuntimeException("transacton rollback");
}
 
Example #8
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 发起分布式事务
 *
 * @return string string
 */
@GlobalTransactional
public String doTransactionCommit() {
    //第一个TCC 事务参与者
    boolean result = tccActionOne.prepare(null, 1);
    if (!result) {
        throw new RuntimeException("TccActionOne failed.");
    }
    List list = new ArrayList();
    list.add("c1");
    list.add("c2");
    result = tccActionTwo.prepare(null, "two", list);
    if (!result) {
        throw new RuntimeException("TccActionTwo failed.");
    }
    return RootContext.getXID();
}
 
Example #9
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * Do transaction rollback string.
 *
 * @param map the map
 * @return the string
 */
@GlobalTransactional
public String doTransactionRollback(Map map) {
    //第一个TCC 事务参与者
    boolean result = tccActionOne.prepare(null, 1);
    if (!result) {
        throw new RuntimeException("TccActionOne failed.");
    }
    List list = new ArrayList();
    list.add("c1");
    list.add("c2");
    result = tccActionTwo.prepare(null, "two", list);
    if (!result) {
        throw new RuntimeException("TccActionTwo failed.");
    }
    map.put("xid", RootContext.getXID());
    throw new RuntimeException("transacton rollback");
}
 
Example #10
Source File: AccountController.java    From spring-cloud-alibaba with Apache License 2.0 6 votes vote down vote up
@PostMapping(value = "/account", produces = "application/json")
public String account(String userId, int money) {
	LOGGER.info("Account Service ... xid: " + RootContext.getXID());

	if (random.nextBoolean()) {
		throw new RuntimeException("this is a mock Exception");
	}

	int result = jdbcTemplate.update(
			"update account_tbl set money = money - ? where user_id = ?",
			new Object[] { money, userId });
	LOGGER.info("Account Service End ... ");
	if (result == 1) {
		return SUCCESS;
	}
	return FAIL;
}
 
Example #11
Source File: SeataHandlerInterceptor.java    From spring-cloud-alibaba with Apache License 2.0 6 votes vote down vote up
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
		Object handler) {

	String xid = RootContext.getXID();
	String rpcXid = request.getHeader(RootContext.KEY_XID);
	if (log.isDebugEnabled()) {
		log.debug("xid in RootContext {} xid in RpcContext {}", xid, rpcXid);
	}

	if (xid == null && rpcXid != null) {
		RootContext.bind(rpcXid);
		if (log.isDebugEnabled()) {
			log.debug("bind {} to RootContext", rpcXid);
		}
	}
	return true;
}
 
Example #12
Source File: SeataHandlerInterceptor.java    From spring-cloud-alibaba with Apache License 2.0 6 votes vote down vote up
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
		Object handler, Exception e) {

	String rpcXid = request.getHeader(RootContext.KEY_XID);

	if (StringUtils.isEmpty(rpcXid)) {
		return;
	}

	String unbindXid = RootContext.unbind();
	if (log.isDebugEnabled()) {
		log.debug("unbind {} from RootContext", unbindXid);
	}
	if (!rpcXid.equalsIgnoreCase(unbindXid)) {
		log.warn("xid in change during RPC from {} to {}", rpcXid, unbindXid);
		if (unbindXid != null) {
			RootContext.bind(unbindXid);
			log.warn("bind {} back to RootContext", unbindXid);
		}
	}
}
 
Example #13
Source File: ActivityServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
@GlobalTransactional
public String doActivity(boolean commit){
    //第一个TCC 事务参与者
    boolean result = actionOne.prepare(null, 1);
    if(!commit || !result){
        throw new RuntimeException("TccActionOne failed.");
    }

    //第二个TCC 事务参与者
    List list = new ArrayList();
    list.add("c1");
    list.add("c2");
    result = actionTwo.prepare(null, "two", list);
    if(!result){
        throw new RuntimeException("TccActionTwo failed.");
    }

    return RootContext.getXID();
}
 
Example #14
Source File: PayServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 事务传播特性设置为 REQUIRES_NEW 开启新的事务
 *
 * @param userId 用户 ID
 * @param price  扣减金额
 * @return
 * @throws Exception
 */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@Override
public boolean reduceBalance(Long userId, Integer price) throws Exception {
    log.info("=============PAY=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.PAY);
    log.info("当前 XID: {}", RootContext.getXID());

    checkBalance(userId, price);

    log.info("开始扣减用户 {} 余额", userId);
    Integer record = accountDao.reduceBalance(price);
    log.info("扣减用户 {} 余额结果:{}", userId, record > 0 ? "操作成功" : "扣减余额失败");

    return record > 0;

}
 
Example #15
Source File: SeataFeignClient.java    From spring-cloud-alibaba with Apache License 2.0 6 votes vote down vote up
private Request getModifyRequest(Request request) {

		String xid = RootContext.getXID();

		if (StringUtils.isEmpty(xid)) {
			return request;
		}

		Map<String, Collection<String>> headers = new HashMap<>(MAP_SIZE);
		headers.putAll(request.headers());

		List<String> seataXid = new ArrayList<>();
		seataXid.add(xid);
		headers.put(RootContext.KEY_XID, seataXid);

		return Request.create(request.method(), request.url(), headers, request.body(),
				request.charset());
	}
 
Example #16
Source File: StorageController.java    From spring-cloud-alibaba with Apache License 2.0 5 votes vote down vote up
@GetMapping(value = "/storage/{commodityCode}/{count}", produces = "application/json")
public String echo(@PathVariable String commodityCode, @PathVariable int count) {
	LOGGER.info("Storage Service Begin ... xid: " + RootContext.getXID());
	int result = jdbcTemplate.update(
			"update storage_tbl set count = count - ? where commodity_code = ?",
			new Object[] { count, commodityCode });
	LOGGER.info("Storage Service End ... ");
	if (result == 1) {
		return SUCCESS;
	}
	return FAIL;
}
 
Example #17
Source File: StorageServiceImpl.java    From dubbo-samples with Apache License 2.0 5 votes vote down vote up
@Override
public void deduct(String commodityCode, int count) {
    LOGGER.info("Storage Service Begin ... xid: " + RootContext.getXID());
    LOGGER.info("Deducting inventory SQL: update storage_tbl set count = count - {} where commodity_code = {}",
            count, commodityCode);

    jdbcTemplate.update("update storage_tbl set count = count - ? where commodity_code = ?",
            new Object[]{count, commodityCode});
    LOGGER.info("Storage Service End ... ");

}
 
Example #18
Source File: AssignServiceImpl.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
@Override
@Transactional
@GlobalTransactional
public AssetAssign increaseAmount(String id) {
	LOGGER.info("Assign Service Begin ... xid: " + RootContext.getXID() + "\n");
	AssetAssign assetAssign = assignRepository.findById(id).get();
	assetAssign.setStatus("2");
	assignRepository.save(assetAssign);

	// remote call asset service
	assetService.increase();
	return assetAssign;
}
 
Example #19
Source File: OrderServiceImpl.java    From dubbo-samples with Apache License 2.0 5 votes vote down vote up
@Override
public Order create(String userId, String commodityCode, int orderCount) {
    LOGGER.info("Order Service Begin ... xid: " + RootContext.getXID());

    // calculate payment
    int orderMoney = calculate(commodityCode, orderCount);

    // debit from the account
    accountService.debit(userId, orderMoney);

    final Order order = new Order();
    order.userId = userId;
    order.commodityCode = commodityCode;
    order.count = orderCount;
    order.money = orderMoney;

    KeyHolder keyHolder = new GeneratedKeyHolder();

    LOGGER.info("Order Service SQL: insert into order_tbl (user_id, commodity_code, count, money) values ({}, {}, {}, {})", userId, commodityCode, orderCount, orderMoney);

    jdbcTemplate.update(con -> {
        PreparedStatement pst = con.prepareStatement(
                "insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)",
                PreparedStatement.RETURN_GENERATED_KEYS);
        pst.setObject(1, order.userId);
        pst.setObject(2, order.commodityCode);
        pst.setObject(3, order.count);
        pst.setObject(4, order.money);
        return pst;
    }, keyHolder);

    order.id = keyHolder.getKey().longValue();

    LOGGER.info("Order Service End ... Created " + order);

    return order;
}
 
Example #20
Source File: AutoCpsLocalTransactionExecutor.java    From EasyTransaction with Apache License 2.0 5 votes vote down vote up
public static <R> R executeWithGlobalLockCheck(Callable<R> call) throws Exception {
    try {
        RootContext.bind("Local Tranaction with Global lock support");
        return call.call();
    } finally {
        RootContext.unbind();
    }
}
 
Example #21
Source File: AbstractAutoCpsMethod.java    From EasyTransaction with Apache License 2.0 5 votes vote down vote up
@Override
public final R doAutoCpsBusiness(P param) {

    TransactionId transactionId = MetaDataFilter.getMetaData(EasytransConstant.CallHeadKeys.PARENT_TRX_ID_KEY);
    String xid = getFescarXid(transactionId);

    try {
        RootContext.bind(xid);
        return doBusiness(param);
    } finally {
        RootContext.unbind();
    }
}
 
Example #22
Source File: SeataHystrixConcurrencyStrategy.java    From spring-cloud-alibaba with Apache License 2.0 5 votes vote down vote up
@Override
public K call() throws Exception {
	try {
		RequestContextHolder.setRequestAttributes(requestAttributes);
		RootContext.bind(xid);
		return actual.call();
	} finally {
		RootContext.unbind();
		RequestContextHolder.resetRequestAttributes();
	}
}
 
Example #23
Source File: TransactionalSQLExecutionHook.java    From shardingsphere with Apache License 2.0 5 votes vote down vote up
@Override
public void start(final String dataSourceName, final String sql, final List<Object> parameters,
                  final DataSourceMetaData dataSourceMetaData, final boolean isTrunkThread, final Map<String, Object> shardingExecuteDataMap) {
    if (isTrunkThread) {
        if (RootContext.inGlobalTransaction()) {
            ExecutorDataMap.getValue().put(SEATA_TX_XID, RootContext.getXID());
        }
    } else if (!RootContext.inGlobalTransaction() && shardingExecuteDataMap.containsKey(SEATA_TX_XID)) {
        RootContext.bind((String) shardingExecuteDataMap.get(SEATA_TX_XID));
        seataBranch = true;
    }
}
 
Example #24
Source File: StorageServiceImpl.java    From demo-seata-springcloud with Apache License 2.0 5 votes vote down vote up
/**
 * 新增
 * 
 * @param storage
 * @return
 * @author sly
 * @time 2019年6月12日
 */
@Override
public Map<String, Object> insert(@RequestBody Storage storage) {
	System.out.println(RootContext.getXID());
	//int a = 10/0;
	storageMapper.insert(storage);
	
	
	Map<String, Object> result = new HashMap<>(16);
	result.put("status", 200);
	result.put("message", "新增成功!");
	return result;
}
 
Example #25
Source File: OrderServiceImpl.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
@GlobalTransactional
@Override
public OperationResponse placeOrder(PlaceOrderRequestVO placeOrderRequestVO) throws Exception {
    log.info("=============ORDER=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);
    log.info("当前 XID: {}", RootContext.getXID());

    Integer amount = 1;
    Integer price = placeOrderRequestVO.getPrice();

    Order order = Order.builder()
                       .userId(placeOrderRequestVO.getUserId())
                       .productId(placeOrderRequestVO.getProductId())
                       .status(OrderStatus.INIT)
                       .payAmount(price)
                       .build();

    Integer saveOrderRecord = orderDao.saveOrder(order);

    log.info("保存订单{}", saveOrderRecord > 0 ? "成功" : "失败");

    // 扣减库存
    boolean operationStorageResult = storageService.reduceStock(placeOrderRequestVO.getProductId(), amount);

    // 扣减余额
    boolean operationBalanceResult = payService.reduceBalance(placeOrderRequestVO.getUserId(), price);

    log.info("=============ORDER=================");
    DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);

    Integer updateOrderRecord = orderDao.updateOrder(order.getId(), OrderStatus.SUCCESS);
    log.info("更新订单:{} {}", order.getId(), updateOrderRecord > 0 ? "成功" : "失败");

    return OperationResponse.builder()
                            .success(operationStorageResult && operationBalanceResult)
                            .build();
}
 
Example #26
Source File: TransactionalSQLExecutionHookTest.java    From shardingsphere with Apache License 2.0 5 votes vote down vote up
@Test
public void assertChildThreadExecuteFailed() {
    executionHook.start("ds", "SELECT 1", Collections.emptyList(), dataSourceMetaData, false, shardingExecuteDataMap);
    assertTrue(RootContext.inGlobalTransaction());
    executionHook.finishFailure(new RuntimeException());
    assertFalse(RootContext.inGlobalTransaction());
}
 
Example #27
Source File: AssetServiceImpl.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
@Override
public int increase() {
    LOGGER.info("Asset Service Begin ... xid: " + RootContext.getXID() + "\n");
    Asset asset = assetRepository.findById(ASSET_ID).get();
    asset.setAmount(asset.getAmount().add(new BigDecimal("1")));
    assetRepository.save(asset);
    throw new RuntimeException("test exception for seata, your transaction should be rollbacked,asset=" + asset);
}
 
Example #28
Source File: TransactionalSQLExecutionHookTest.java    From shardingsphere with Apache License 2.0 5 votes vote down vote up
@Test
public void assertTrunkThreadExecute() {
    RootContext.bind("xid");
    executionHook.start("ds", "SELECT 1", Collections.emptyList(), dataSourceMetaData, true, shardingExecuteDataMap);
    assertThat(ExecutorDataMap.getValue().get("SEATA_TX_XID"), is(RootContext.getXID()));
    executionHook.finishSuccess();
    assertTrue(RootContext.inGlobalTransaction());
}
 
Example #29
Source File: SeataRestTemplateInterceptor.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
    HttpRequestWrapper requestWrapper = new HttpRequestWrapper(httpRequest);
    String xid = RootContext.getXID();
    if (StringUtils.isNotEmpty(xid)) {
        requestWrapper.getHeaders().add(RootContext.KEY_XID, xid);
    }

    return clientHttpRequestExecution.execute(requestWrapper, bytes);
}
 
Example #30
Source File: StorageClient.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
public void deduct(String commodityCode, int orderCount) {
    System.out.println("business to storage " + RootContext.getXID());
    String url = "http://127.0.0.1:8081/api/storage/deduct?commodityCode=" + commodityCode + "&count=" + orderCount;
    try {
        restTemplate.getForEntity(url, Void.class);
    } catch (Exception e) {
        log.error("deduct url {} ,error:", url, e);
        throw new RuntimeException();
    }
}