ballerina 学习十八 事务编程
事务在分布式开发,以及微服务开发中是比较重要的
ballerina 支持 本地事务、xa 事务、分布式事务 ,但是具体的服务实现起来需要按照ballerian 的事务模型 infection agreement
基本事务使用(本地事务)
- 参考代码(数据库)
import ballerina/mysql;
import ballerina/io;
endpoint mysql:Client testDB {
host: "localhost",
port: 3306,
name: "testdb",
username: "root",
password: "root",
poolOptions: { maximumPoolSize: 5 }
};function main(string... args) {
var ret = testDB->update("CREATE TABLE CUSTOMER (ID INT, NAME
VARCHAR(30))");
handleUpdate(ret, "Create CUSTOMER table"); ret = testDB->update("CREATE TABLE SALARY (ID INT, MON_SALARY FLOAT)");
handleUpdate(ret, "Create SALARY table");
transaction with retries = 4, oncommit = onCommitFunction,
onabort = onAbortFunction {
var result = testDB->update("INSERT INTO CUSTOMER(ID,NAME)
VALUES (1, 'Anne')");
result = testDB->update("INSERT INTO SALARY (ID, MON_SALARY)
VALUES (1, 2500)");
match result {
int c => {
io:println("Inserted count: " + c);
if (c == 0) {
abort;
}
}
error err => {
retry;
}
}
} onretry {
io:println("Retrying transaction");
}
ret = testDB->update("DROP TABLE CUSTOMER");
handleUpdate(ret, "Drop table CUSTOMER"); ret = testDB->update("DROP TABLE SALARY");
handleUpdate(ret, "Drop table SALARY");
testDB.stop();
}
function onCommitFunction(string transactionId) {
io:println("Transaction: " + transactionId + " committed");
}
function onAbortFunction(string transactionId) {
io:println("Transaction: " + transactionId + " aborted");
}
function handleUpdate(int|error returned, string message) {
match returned {
int retInt => io:println(message + " status: " + retInt);
error err => io:println(message + " failed: " + err.message);
}
}
分布式事务
import ballerina/math;
import ballerina/http;
import ballerina/log;
import ballerina/transactions;
@http:ServiceConfig {
basePath: "/"
}
service<http:Service> InitiatorService bind { port: 8080 } { @http:ResourceConfig {
methods: ["GET"],
path: "/"
}
init(endpoint conn, http:Request req) {
http:Response res = new;
log:printInfo("Initiating transaction...");
transaction with oncommit = printCommit,
onabort = printAbort {
log:printInfo("Started transaction: " +
transactions:getCurrentTransactionId());
boolean successful = callBusinessService();
if (successful) {
res.statusCode = http:OK_200;
} else {
res.statusCode = http:INTERNAL_SERVER_ERROR_500;
abort;
}
} var result = conn->respond(res);
match result {
error e =>
log:printError("Could not send response back to client", err = e);
() =>
log:printInfo("Sent response back to client");
}
}
}
function printAbort(string transactionId) {
log:printInfo("Initiated transaction: " + transactionId + " aborted");
}
function printCommit(string transactionId) {
log:printInfo("Initiated transaction: " + transactionId + " committed");
}function callBusinessService() returns boolean {
endpoint http:Client participantEP {
url: "http://localhost:8889/stockquote/update"
}; boolean successful; float price = math:randomInRange(200, 250) + math:random();
json bizReq = { symbol: "GOOG", price: price };
http:Request req = new;
req.setJsonPayload(bizReq);
var result = participantEP->post("", request = req);
log:printInfo("Got response from bizservice");
match result {
http:Response res => {
successful = (res.statusCode == http:OK_200) ? true : false;
}
error => successful = false;
}
return successful;
}
import ballerina/log;
import ballerina/io;
import ballerina/http;
import ballerina/transactions;
@http:ServiceConfig {
basePath: "/stockquote"
}
service<http:Service> ParticipantService bind { port: 8889 } { @http:ResourceConfig {
path: "/update"
}
updateStockQuote(endpoint conn, http:Request req) {
log:printInfo("Received update stockquote request");
http:Response res = new;
transaction with oncommit = printParticipantCommit,
onabort = printParticipantAbort {
log:printInfo("Joined transaction: " +
transactions:getCurrentTransactionId());
var updateReq = untaint req.getJsonPayload();
match updateReq {
json updateReqJson => {
string msg =
io:sprintf("Update stock quote request received.
symbol:%j, price:%j",
updateReqJson.symbol,
updateReqJson.price);
log:printInfo(msg); json jsonRes = { "message": "updating stock" };
res.statusCode = http:OK_200;
res.setJsonPayload(jsonRes);
}
error e => {
res.statusCode = http:INTERNAL_SERVER_ERROR_500;
res.setPayload(e.message);
log:printError("Payload error occurred!", err = e);
}
} var result = conn->respond(res);
match result {
error e =>
log:printError("Could not send response back to initiator",
err = e);
() =>
log:printInfo("Sent response back to initiator");
}
}
}
}
function printParticipantAbort(string transactionId) {
log:printInfo("Participated transaction: " + transactionId + " aborted");
}
function printParticipantCommit(string transactionId) {
log:printInfo("Participated transaction: " + transactionId + " committed");
}
参考资料
https://ballerina.io/learn/by-example/transactions-distributed.html
https://ballerina.io/learn/by-example/local-transactions.html
ballerina 学习十八 事务编程的更多相关文章
- ballerina 学习十九 安全编程
ballerina 内部提供了几种常用的安全开发模型,token 认证(jwt) basic auth jwt 安全 参考代码 import ballerina/http; http:AuthPr ...
- WCF学习笔记之事务编程
WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...
- javaweb学习总结(三十八)——事务
一.事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐,对应于如下两条sql语句 update from account set mone ...
- Python学习札记(三十八) 面向对象编程 Object Oriented Program 9
参考:多重继承 NOTE #!/usr/bin/env python3 class Animal(object): def __init__(self, name): self.name = name ...
- 强化学习(十八) 基于模拟的搜索与蒙特卡罗树搜索(MCTS)
在强化学习(十七) 基于模型的强化学习与Dyna算法框架中,我们讨论基于模型的强化学习方法的基本思路,以及集合基于模型与不基于模型的强化学习框架Dyna.本文我们讨论另一种非常流行的集合基于模型与不基 ...
- spring学习 十八 spring的声明事物
1.编程式事务: 1.1 由程序员编程事务控制代码.commit与rollback都需要程序员决定在哪里调用,例如jdbc中conn.setAutoCimmit(false),conn.commit( ...
- Scala学习十八——高级类型
一.本章要点 单例类型可用于方法串接和带对象参数的方法 类型投影对所有外部类的对象都包含了其他内部类的实例 类型别名给类型指定一个短小的名称 结构类型等效于”鸭子类型“ 存在类型为泛型的通配参数提供了 ...
- Java编程思想学习(十六) 并发编程
线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础. 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是 ...
- Storm系列(十八)事务介绍
功能:将多个tuple组合成为一个批次,并保障每个批次的tuple被且仅被处理一次. storm事务处理中,把一个批次的tuple的处理分为两个阶段processing和commit阶段. proce ...
随机推荐
- 2017中国大学生程序设计竞赛-哈尔滨站 Solution
A - Palindrome 题意:给出一个字符串,找出其中有多少个子串满足one-half-palindromic 的定义 思路:其实就是找一个i, j 使得 以i为中轴的回文串长度和以j为中轴的 ...
- Java final finally finalize有什么不同
① final 可以用来修饰类.方法.变量, ----final修饰的class代表不可以继承扩展 ----final的变量不可以修改 ----final的方法不可以override ----fina ...
- netty4.1.6源码2-------创建服务端的channel
1. netty在哪里调用jdk底层的socket去创建netty服务端的socket. 2. 在哪里accept连接. 服务端的启动: 1. 调用jdk底层的api去创建jdk的服务端的channe ...
- 试着用React写项目-利用styled-components解决样式问题
转载请注明出处:王亟亟的大牛之路 啰嗦之前先安利,会渐渐丰富前端的知识点 https://github.com/ddwhan0123/Useful-Open-Source-Android 昨天用web ...
- OpenDayLight Helium实验三 OpenDaylight二层转发机制实验
本文基于OpenDaylight二层转发机制实验 而成 在SDN网络中,处于末端的主机并不知道其连接的网络是SDN,某台主机要发送数据包到另一台主机,仍然需要进行IP到MAC地址的ARP解析.SDN网 ...
- tar: Cowardly refusing to create an empty archive 问题
在解压 .tar.gz文件的时候遇到了这个解压的问题. 原命令:tar -zcvf ···.tar.gz 提示:tar: Cowardly refusing to create an empty ar ...
- Google V8 引擎 原理详解
V8 引擎概览 V8 引擎简介 Google V8 引擎使用 C++ 代码编写,实现了 ECMAScript 规范的第五版,可以运行在所有的主流 操作系统中,甚至可以运行在移动终端 ( 基于 ARM ...
- Gym 101246D Fire in the Country(dfs求SG函数)
http://codeforces.com/gym/101246/problem/D 题意: 给定一个无向有环图,大火从1点开始,每个时间点与它相邻的点也将会着火,现在有两个人轮流操作机器人,机器人从 ...
- socket可读可写就绪条件
参考 <UNIX 网络编程卷1>中的<第6章 I/O复用> 一. 满足下列四个条件中的任何一个时,一个套接字准备好读. 该套接字接收缓冲区中的数据字节数大于等于套接字接收缓存区 ...
- 解决QML Window 增加radius效果
做开发时,突然遇到 一个需要模态展示的对话框,做出来后,发现还要radius属性,增加时发现,Window控件不支持这个属性.如果是以前,原本就打算放弃了,但想一下,这种应该是支持的,既然接口上没有, ...