金融系统中事务

news/2024/11/8 21:51:45/

金融服务行业需要处理大量的交易和请求,Java的多线程能力可以有效地管理这些并发操作,确保系统的响应性和效率。

金融服务行业中,例如一个股票交易平台,它需要处理大量的买入和卖出请求,交易逻辑会涉及数据库交互、错误处理和事务管理等方面的复杂性。这就是一个 Java 多线程能力的点型应用了,V 哥从项目中剥离了这个案例,分享给你参考。

  1. 定义交易请求和响应
    金融服务行业中,定义清晰的交易请求和响应模型是确保交易处理正确性和有效通信的关键。来看一下如何定义交易请求和响应:

  2. 定义交易请求(TradeRequest)
    交易请求通常是一个对象,封装了执行交易所需的所有信息。以下是设计TradeRequest类的一些关键点:

唯一标识符(Trade ID):每个交易请求都应该有一个唯一的标识符,以便于跟踪和管理。
股票代码(Stock Symbol):表示交易涉及的股票的代码或名称。
交易类型(Trade Type):买入(Buy)或卖出(Sell)。
交易数量(Quantity):要交易的股票数量。
交易价格(Price):交易请求的价格。
用户信息(User Info):发起交易的用户信息,可能包括用户ID或账户信息。
时间戳(Timestamp):请求创建的时间,用于记录交易请求的时间。
public class TradeRequest {
private final String tradeId; // 交易ID
private final String stockSymbol; // 股票代码
private final TradeType type; // 交易类型:买入或卖出
private final int quantity; // 交易数量
private final double price; // 交易价格
private final String userId; // 用户ID
private final long timestamp; // 时间戳

// 使用构造函数初始化属性
public TradeRequest(String tradeId, String stockSymbol, TradeType type,int quantity, double price, String userId) {this.tradeId = tradeId;this.stockSymbol = stockSymbol;this.type = type;this.quantity = quantity;this.price = price;this.userId = userId;this.timestamp = System.currentTimeMillis();
}// Getters方法,提供访问属性的方式
public String getTradeId() { return tradeId; }
public String getStockSymbol() { return stockSymbol; }
public TradeType getType() { return type; }
public int getQuantity() { return quantity; }
public double getPrice() { return price; }
public String getUserId() { return userId; }
public long getTimestamp() { return timestamp; }

}

// TradeType枚举定义了交易的类型
public enum TradeType {
BUY,
SELL
}
2. 定义交易响应(TradeResponse)
交易响应对象用于向发起交易请求的客户端返回交易处理的结果。以下是设计TradeResponse类的一些关键点:

交易ID(Trade ID):与请求对应的交易标识符,用于匹配请求和响应。
成功标志(Success Flag):表示交易是否成功的布尔值。
消息(Message):包含成功或错误信息的描述性消息。
交易详情(Trade Details):可选,如果交易成功,可能包含交易的详细信息,如执行价格、时间等。
public class TradeResponse {
private final String tradeId; // 交易ID
private final boolean success; // 成功标志
private final String message; // 消息描述

// 构造函数
public TradeResponse(String tradeId, boolean success, String message) {this.tradeId = tradeId;this.success = success;this.message = message;
}// Getters方法
public String getTradeId() { return tradeId; }
public boolean isSuccess() { return success; }
public String getMessage() { return message; }

}
代码实现逻辑
构造函数:用于创建对象时初始化所有必要的属性。
Getters方法:提供访问对象属性的方式,这是Java中封装的一种实现方式。
枚举类型(TradeType):使用枚举来限制交易类型的值,提高代码的可读性和安全性。
通过这样的设计,我们可以确保每个交易请求都包含了所有必要信息,并且交易响应可以清晰地传达处理结果。这种模式有助于开发人员编写清晰、易于维护的代码,同时也便于调试和跟踪交易处理过程中的问题。

  1. 模拟数据库交互
    我们使用一个简单的TradeDatabase类来模拟数据库交互。

import java.util.concurrent.ConcurrentHashMap;

public class TradeDatabase {
private final ConcurrentHashMap<String, Double> stockPrices = new ConcurrentHashMap<>();

public synchronized boolean updateStockPrice(String stockSymbol, double newPrice) {// 模拟数据库更新操作stockPrices.put(stockSymbol, newPrice);return true;
}public double getPrice(String stockSymbol) {return stockPrices.getOrDefault(stockSymbol, -1.0);
}

}
3. 交易处理器
TradeProcessor类现在包括数据库交互和事务管理。

public class TradeProcessor {
private final ExecutorService executorService;
private final TradeDatabase tradeDatabase;

public TradeProcessor(int poolSize, TradeDatabase tradeDatabase) {this.executorService = Executors.newFixedThreadPool(poolSize);this.tradeDatabase = tradeDatabase;
}public void processTrade(TradeRequest tradeRequest) {executorService.submit(() -> {try {TradeResponse response = executeTrade(tradeRequest);System.out.println(response.getMessage());} catch (Exception e) {System.err.println("Error processing trade: " + e.getMessage());}});
}private TradeResponse executeTrade(TradeRequest tradeRequest) throws Exception {// 检查股票价格double currentPrice = tradeDatabase.getPrice(tradeRequest.getStockSymbol());if (currentPrice == -1.0) {return new TradeResponse(tradeRequest.getTradeId(), false, "Stock symbol not found.");}// 简单的价格比较逻辑if (tradeRequest.getPrice() != currentPrice) {return new TradeResponse(tradeRequest.getTradeId(), false, "Price mismatch.");}// 模拟事务性更新价格boolean transactionSuccess = tradeDatabase.updateStockPrice(tradeRequest.getStockSymbol(), currentPrice + 0.05);if (!transactionSuccess) {return new TradeResponse(tradeRequest.getTradeId(), false, "Failed to update stock price.");}return new TradeResponse(tradeRequest.getTradeId(), true, "Trade executed successfully.");
}// shutdown method

}
4. 错误处理
在executeTrade方法中,我们添加了基本的错误处理逻辑,返回错误信息。

  1. 主程序
    主程序现在包括了TradeDatabase的创建。

public class StockTradingPlatform {
public static void main(String[] args) {
int poolSize = 10;
int numTrades = 50;
TradeDatabase tradeDatabase = new TradeDatabase();

    TradeProcessor tradeProcessor = new TradeProcessor(poolSize, tradeDatabase);TradeGenerator tradeGenerator = new TradeGenerator(tradeProcessor);tradeGenerator.generateTrades(numTrades);// 等待所有交易处理完成tradeProcessor.shutdown();System.out.println("All trades processed. System shutting down.");
}

}
代码中的关键解释:
TradeDatabase 类模拟了数据库操作,使用了ConcurrentHashMap来存储股票价格,并提供了同步的方法来更新价格。
TradeProcessor 类现在包括了执行交易的方法,该方法首先检查股票的当前价格,然后尝试执行交易并更新数据库。如果任何步骤失败,将返回错误响应。
executeTrade 方法中的逻辑模拟了事务性操作,确保交易的一致性。
主程序创建了TradeDatabase实例,并将其传递给TradeProcessor。
根据你的业务逻辑,数据库操作会更复杂,比如涉及连接池、更复杂的事务管理、网络延迟、并发控制等这些。

最后


http://www.ppmy.cn/news/1545465.html

相关文章

《JavaEE进阶》----20.<基于Spring图书管理系统(登录+添加图书)>

PS&#xff1a;关于接口定义 接口定义&#xff0c;通常由服务器提供方来定义。 1.路径&#xff1a;自己定义 2.参数&#xff1a;根据需求考虑&#xff0c;我们这个接口功能完成需要哪些信息。 3.返回结果&#xff1a;考虑我们能为对方提供什么。站在对方角度考虑。 我们使用到的…

集合进阶------泛型(JAVA笔记第三十期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 泛型概念泛型类泛型接口泛型接口的实现类泛型方法可变参数的泛型方法 泛型的通配符 泛型概念 泛型&#xff0c;顾名思义&#xff0c;广泛的类型&#xff0c;使用泛型可以帮助我们…

基于springboot+vue实现的任务管理系统(源码+L文)4-103

第4章 系统设计 4.1 总体功能设计 员工&#xff0c;经理&#xff0c;管理员都需要登录才能进入任务管理系统&#xff0c;使用者登录时会在后台判断使用的权限类型&#xff0c;包括一般使用者和管理者,一般使用者为员工和经理&#xff0c;对员工只能提供任务信息显示查询&…

【JAVA】Java基础—Java开发环境搭建:安装JDK与IDE(如IntelliJ IDEA、Eclipse)

Java是一种强大的编程语言&#xff0c;广泛应用于各种领域&#xff0c;包括企业级应用、移动应用&#xff08;如Android&#xff09;、Web应用和大数据处理等。Java的“编写一次&#xff0c;到处运行”&#xff08;Write Once, Run Anywhere, WORA&#xff09;特性使得它在跨平…

【整理向】c++,Java与Python的面向对象(OOP)之间的异同

C、Java 和 Python 都是支持面向对象编程&#xff08;OOP&#xff09;的语言&#xff0c;但它们在实现 OOP 的方式上存在一些相似性和差异。我们可以从类和对象、继承、封装、多态等方面对比它们的异同。 1. 类和对象 相同点&#xff1a;C、Java 和 Python 都使用类作为对象的…

前端UniApp面试题及参考答案(100道题)

目录 UniApp 支持哪些平台? UniApp 在不同平台上的表现有何差异? 如何处理 UniApp 中的平台差异? UniApp 项目创建与目录结构 项目创建 目录结构 如何创建一个 UniApp 项目? UniApp 项目的基本目录结构是什么样的? 解释一下 UniApp 中的页面生命周期钩子函数有哪…

汇编语言:查找以‘$’结尾的字符串str中数字字符的个数并输出

两个子函数&#xff0c;一个子函数统计字符串中字符的个数并放在CX中 另一个输出AX中的无符号整数 &#xff0c;可以是0&#xff0c;但最大只能是4位数&#xff0c;并且前三位不能超过255 在主函数中先调用统计字符个数的子函数COUNT&#xff0c;然后把CX中的数复制到AX中&am…

mybatis+postgresql,无感读写json字段

1.实体类中字段类型 import com.alibaba.fastjson.JSONObject;Data public class TestDto {private String name;//对应数据库的JSON字段private JSONObject page_detail;} 2.自定义实现typeHandler package base.utils;import com.alibaba.fastjson.JSONObject; import org…