io.seata.spring.annotation.GlobalTransactional Java Examples

The following examples show how to use io.seata.spring.annotation.GlobalTransactional. 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: SeataTxController.java    From zuihou-admin-cloud with Apache License 2.0 8 votes vote down vote up
/**
 * 正常回滚, 是分布式事务回滚的效果
 * <p>
 * 目前存在2个问题:
 * 1, seata-all 1.0.0 SeataHystrixConcurrencyStrategy 和 本项目中 ThreadLocalHystrixConcurrencyStrategy 冲突,导致事务回滚失效。
 * 临时解决方案是将 ThreadLocalHystrixConcurrencyStrategy 中内部类 WrappedCallable 中注释的4行代码释放开
 * <p>
 * 2,insert into zuihou_base_0000.m_product 语法,还是无法回滚, 想要测试,请勿在请求头中传递 tenant 参数,并将m_product表和m_order 表复制到 zuihou_defaults
 *
 * @param
 * @return
 */
@PostMapping("/save/rollback")
@GlobalTransactional
public Boolean placeOrderRollback() {
    Product data = Product.builder()
            .name("你的名字")
            .stock(123)
            .build();
    log.info("data={}", data);
    R<Product> save = this.seataTestApi.save(data);

    //在这里打断点可以看到 m_product 表的数据已经插入
    //但等执行完整个方法,发现 m_product 数据被删除
    int i = 1 / 0;
    Order entity = Order.builder()
            .code(data.getName() + "code")
            .name(data.getName())
            .build();
    this.orderService.save(entity);

    return true;
}
 
Example #2
Source File: OrderServiceImpl.java    From SpringBlade with Apache License 2.0 6 votes vote down vote up
@Override
@GlobalTransactional
@Transactional(rollbackFor = Exception.class)
public boolean createOrder(String userId, String commodityCode, Integer count) {
	int maxCount = 100;
	BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
	Order order = new Order()
		.setUserId(userId)
		.setCommodityCode(commodityCode)
		.setCount(count)
		.setMoney(orderMoney);
	int cnt1 = baseMapper.insert(order);
	int cnt2 = storageClient.deduct(commodityCode, count);
	if (cnt2 < 0) {
		throw new ServiceException("创建订单失败");
	} else if (count > maxCount) {
		throw new ServiceException("超过订单最大值,创建订单失败");
	}
	return cnt1 > 0 && cnt2 > 0;
}
 
Example #3
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 #4
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 #5
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 #6
Source File: TransferServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 转账操作
 * @param from  扣钱账户
 * @param to  加钱账户
 * @param amount  转账金额
 * @return
 */
@Override
@GlobalTransactional
public boolean transfer(final String from, final String to, final double amount) {
    //扣钱参与者,一阶段执行
    boolean ret = firstTccAction.prepareMinus(null, from, amount);

    if(!ret){
        //扣钱参与者,一阶段失败; 回滚本地事务和分布式事务
        throw new RuntimeException("账号:["+from+"] 预扣款失败");
    }

    //加钱参与者,一阶段执行
    ret = secondTccAction.prepareAdd(null, to, amount);

    if(!ret){
        throw new RuntimeException("账号:["+to+"] 预收款失败");
    }

    System.out.println(String.format("transfer amount[%s] from [%s] to [%s] finish.", String.valueOf(amount), from, to));
    return true;
}
 
Example #7
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 #8
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 #9
Source File: GlobalTransactionScanner.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
private boolean existsAnnotation(Class<?>[] classes) {
    if (classes != null && classes.length > 0) {
        for (Class clazz : classes) {
            if (clazz == null) {
                continue;
            }
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                GlobalTransactional trxAnno = method.getAnnotation(GlobalTransactional.class);
                if (trxAnno != null) {
                    return true;
                }

                GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                if (lockAnno != null) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
Example #10
Source File: GlobalTransactionScanner.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
private boolean existsAnnotation(Class<?>[] classes) {
    if (classes != null && classes.length > 0) {
        for (Class clazz : classes) {
            if (clazz == null) {
                continue;
            }
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                GlobalTransactional trxAnno = method.getAnnotation(GlobalTransactional.class);
                if (trxAnno != null) {
                    return true;
                }

                GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                if (lockAnno != null) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
Example #11
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 #12
Source File: OrderServiceImpl.java    From seata-samples with Apache License 2.0 6 votes vote down vote up
/**
 * 创建订单
 * @param order
 * @return
 * 测试结果:
 * 1.添加本地事务:仅仅扣减库存
 * 2.不添加本地事务:创建订单,扣减库存
 */
@Override
@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
public void create(Order order) {
    LOGGER.info("------->交易开始");
    //本地方法
    orderDao.create(order);

    //远程方法 扣减库存
    storageApi.decrease(order.getProductId(),order.getCount());

    //远程方法 扣减账户余额

    LOGGER.info("------->扣减账户开始order中");
    accountApi.decrease(order.getUserId(),order.getMoney());
    LOGGER.info("------->扣减账户结束order中");

    LOGGER.info("------->交易结束");
}
 
Example #13
Source File: StorageService.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
/**
 * 0.8.0 release
 *
 * @throws SQLException
 */
@GlobalTransactional
public void batchUpdate() throws SQLException {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        String sql = "update storage_tbl set count = ?" +
            "    where id = ? and commodity_code = ?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 100);
        preparedStatement.setLong(2, 1);
        preparedStatement.setString(3, "2001");
        preparedStatement.addBatch();
        preparedStatement.setInt(1, 200);
        preparedStatement.setLong(2, 2);
        preparedStatement.setString(3, "2002");
        preparedStatement.addBatch();
        preparedStatement.setInt(1, 300);
        preparedStatement.setLong(2, 3);
        preparedStatement.setString(3, "2003");
        preparedStatement.addBatch();
        preparedStatement.executeBatch();
        connection.commit();
        System.out.println(1 / 0);
    } catch (Exception e) {
        throw e;
    } finally {
        connection.close();
        preparedStatement.close();
    }
}
 
Example #14
Source File: UserController.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
/**
 * seata 全局事务控制
 * @param user
 */
@PostMapping("/seata/user/add")
@GlobalTransactional(rollbackFor = Exception.class) // 开启全局事务
public void add(@RequestBody TbUser user) {
    log.info("globalTransactional begin, Xid:{}", RootContext.getXID());
    // local save
    localSave(user);

    // call provider save
    userService.add(user);

    // test seata globalTransactional
    throw new RuntimeException();
}
 
Example #15
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 5 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.");
    }
    result = tccActionTwo.prepare(null, "two");
    if(!result){
        throw new RuntimeException("TccActionTwo failed.");
    }
    return RootContext.getXID();
}
 
Example #16
Source File: TccTransactionService.java    From seata-samples with Apache License 2.0 5 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.");
    }
    result = tccActionTwo.prepare(null, "two");
    if(!result){
        throw new RuntimeException("TccActionTwo failed.");
    }
    map.put("xid", RootContext.getXID());
    throw new RuntimeException("transacton rollback");
}
 
Example #17
Source File: StorageService.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
/**
 * 0.8.0 release
 *
 * @throws SQLException
 */
@GlobalTransactional
public void batchDelete() throws SQLException {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        String sql = "delete from storage_tbl where  count = ? and commodity_code = ?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 11);
        preparedStatement.setString(2, "2001");
        preparedStatement.addBatch();
        preparedStatement.setInt(1, 22);
        preparedStatement.setString(2, "2002");
        preparedStatement.addBatch();
        preparedStatement.setInt(1, 33);
        preparedStatement.setString(2, "2003");
        preparedStatement.addBatch();
        preparedStatement.executeBatch();
        connection.commit();
        System.out.println(1 / 0);
    } catch (Exception e) {
        throw e;
    } finally {
        connection.close();
        preparedStatement.close();
    }
}
 
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: OrderService.java    From seata-samples with Apache License 2.0 5 votes vote down vote up
/**
 * 下单:创建订单、减库存,涉及到两个服务
 *
 * @param userId
 * @param commodityCode
 * @param count
 */
@GlobalTransactional
@Transactional(rollbackFor = Exception.class)
public void placeOrder(String userId, String commodityCode, Integer count) {
    BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
    Order order = new Order()
            .setUserId(userId)
            .setCommodityCode(commodityCode)
            .setCount(count)
            .setMoney(orderMoney);
    orderDAO.insert(order);
    storageFeignClient.deduct(commodityCode, count);

}
 
Example #20
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 #21
Source File: SendServiceImpl.java    From fw-spring-cloud with Apache License 2.0 5 votes vote down vote up
@GlobalTransactional
@Override
public void sendOrder(FwTradeLog fwTradeLog) {
    fwTradeLog.setStatus(StatusEnum.THREE.getValue());
    fwTradeLog.setStatusDsc(StatusEnum.THREE.getDesc());
    fwTradeLogService.save(fwTradeLog);
    log.info("[订单状态{}]=>{},当前商品id=>{},商品名称=>{}",fwTradeLog.getOrderId(), StatusEnum.THREE.getDesc(),fwTradeLog.getProductId(),fwTradeLog.getProductName());
}
 
Example #22
Source File: OrderServiceImpl.java    From fw-spring-cloud with Apache License 2.0 5 votes vote down vote up
@GlobalTransactional
    @Override
    public void saveAndPayOrder(String productName) {

        FwTradeLog fwTradeLog =new FwTradeLog(StatusEnum.TWO);
        fwTradeLog.setProductId(System.currentTimeMillis());
        fwTradeLog.setProductName(productName);
        fwTradeLogService.save(fwTradeLog);
        log.info("[订单状态{}]=>{},当前商品id=>{},商品名称=>{}",fwTradeLog.getOrderId(), StatusEnum.TWO.getDesc(),fwTradeLog.getProductId(),fwTradeLog.getProductName());

        remoteSendServiceFeign.sendOrder(fwTradeLog);
//        int i=1/0;
    }
 
Example #23
Source File: OrderServiceImpl.java    From fw-spring-cloud with Apache License 2.0 5 votes vote down vote up
@GlobalTransactional
    @Override
    public void saveAndPayOrder(String productName) {

        FwTradeLog fwTradeLog =new FwTradeLog(StatusEnum.TWO);
        fwTradeLog.setProductId(System.currentTimeMillis());
        fwTradeLog.setProductName(productName);
        fwTradeLogService.save(fwTradeLog);
        log.info("[订单状态{}]=>{},当前商品id=>{},商品名称=>{}",fwTradeLog.getOrderId(), StatusEnum.TWO.getDesc(),fwTradeLog.getProductId(),fwTradeLog.getProductName());

        remoteSendServiceFeign.sendOrder(fwTradeLog);
//        int i=1/0;
    }
 
Example #24
Source File: SeataProviderTransactionServiceImpl.java    From spring-boot-samples with Apache License 2.0 5 votes vote down vote up
@Override
@GlobalTransactional
public void createOrder(TbOrder order, TbOrderItem orderItem) {
    orderService.insert(order);
    orderItemService.insert(orderItem);

    // 抛出异常用以测试分布式事务是否回滚
    if (order.getUserId().equals(1L)) {
        throw new RuntimeException("Exception for seata.");
    }
}
 
Example #25
Source File: SeataTxController.java    From zuihou-admin-cloud with Apache License 2.0 5 votes vote down vote up
/**
 * 正常的提交事务
 *
 * @param data
 * @return
 */
@PostMapping("/save")
@GlobalTransactional
public R<Product> saveCommitSuccess(@RequestBody Product data) {
    log.info("data={}", data);
    this.seataTestApi.save(data);
    Order entity = Order.builder()
            .code(data.getName() + "CODE")
            .name(data.getName())
            .build();
    this.orderService.save(entity);
    return R.success(data);
}
 
Example #26
Source File: SeataTxController.java    From zuihou-admin-cloud with Apache License 2.0 5 votes vote down vote up
/**
 * 正常回滚, 是demo服务的本地事务回滚的效果
 *
 * @param data
 * @return
 */
@PostMapping("/save/rollback2")
@GlobalTransactional
public R<Product> saveRollbackSuccess2(@RequestBody Product data) {
    log.info("data={}", data);
    this.seataTestApi.saveEx(data);

    Order entity = Order.builder()
            .code(data.getName() + "CODE")
            .name(data.getName())
            .build();
    this.orderService.save(entity);
    return R.success(data);
}
 
Example #27
Source File: TempOrderController.java    From lion with Apache License 2.0 5 votes vote down vote up
@ApiOperation(value = "全局事务,正常下单", notes = "执行:插入订单表、扣减库存表")
@RequestMapping(value = "/commit", method = {RequestMethod.GET, RequestMethod.POST})
@GlobalTransactional
@Transactional
public Result<String> commit() {
    place("product-1", 1);
    return Result.success("下单成功");
}
 
Example #28
Source File: TempOrderController.java    From lion with Apache License 2.0 5 votes vote down vote up
/**
 * 下单:插入订单表、扣减库存,模拟回滚
 */
@ApiOperation(value = "全局事务,模拟回滚", notes = "执行:插入订单表、扣减库存表")
@RequestMapping(value = "/rollback", method = {RequestMethod.GET, RequestMethod.POST})
@GlobalTransactional
@Transactional
public Result<String> rollback() {
    place("product-1", 1);
    throw new LionException("全局事务 -> 模拟回滚(数据正常)...");
}
 
Example #29
Source File: BusinessServiceImpl.java    From dubbo-samples with Apache License 2.0 5 votes vote down vote up
@Override
@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")
public void purchase(String userId, String commodityCode, int orderCount) {
    LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
    storageService.deduct(commodityCode, orderCount);
    orderService.create(userId, commodityCode, orderCount);
    throw new RuntimeException("xxx");

}
 
Example #30
Source File: HomeController.java    From spring-cloud-alibaba with Apache License 2.0 5 votes vote down vote up
@GlobalTransactional(timeoutMills = 300000, name = "spring-cloud-demo-tx")
@GetMapping(value = "/seata/rest", produces = "application/json")
public String rest() {

	String result = restTemplate.getForObject(
			"http://127.0.0.1:18082/storage/" + COMMODITY_CODE + "/" + ORDER_COUNT,
			String.class);

	if (!SUCCESS.equals(result)) {
		throw new RuntimeException();
	}

	String url = "http://127.0.0.1:18083/order";
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

	MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
	map.add("userId", USER_ID);
	map.add("commodityCode", COMMODITY_CODE);
	map.add("orderCount", ORDER_COUNT + "");

	HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(
			map, headers);

	ResponseEntity<String> response;
	try {
		response = restTemplate.postForEntity(url, request, String.class);
	}
	catch (Exception exx) {
		throw new RuntimeException("mock error");
	}
	result = response.getBody();
	if (!SUCCESS.equals(result)) {
		throw new RuntimeException();
	}

	return SUCCESS;
}