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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2015-06-01 树莓派 2 win 10 IOT