Thông tin chi tiết về bài toán:
Ở đây tôi có một bài toán từ khách hàng như sau: Hãy tạo cho tao một mã đơn hàng (trans_confirm_no) để tao có thể phân biệt được các đơn hàng với nhau với định dạng như này “TMSxxxxx” và nó sẽ phải bắt đầu từ “TMS00001“.
Ngay khi nhận được yêu cầu thì tôi đã bắt tay ngay vào việc code và ngôn ngữ tôi sử dụng cho dự án này là Java spring boot và MSQL.
Cách sử dụng code để generate mã trans_confirm_no
// hàm tạo ra mã trans_confirm_no mới tăng dần
private synchronized String getTransConfirmNoDiorTest(){
String maxTransConfirmNo = transactionDiorMapper.getTransConfirmNo();
log.info("maxTransConfirmNo: {}", maxTransConfirmNo);
StringBuilder result = new StringBuilder();
if (StringUtils.isBlank(maxTransConfirmNo)){
logger.warn("Order transConfirmNo failed, transConfirmNo={}", maxTransConfirmNo);
result.append("00001");
} else {
int maxTransConfirmNoIntValue = Integer.parseInt(maxTransConfirmNo.substring(3)) + 1;
if (maxTransConfirmNoIntValue > 0 && maxTransConfirmNoIntValue < 100000 ) {
int len = 5 - ((Integer)maxTransConfirmNoIntValue).toString().length();
if ( len > 0 ) {
for (int i = 0; i < len ; i++) {
result.append("0");
}
result.append(maxTransConfirmNoIntValue);
} else {
result.append(maxTransConfirmNoIntValue);
}
} else {
result.append("00001");
}
}
log.info("result: {}", result);
return "TMS" + result;
}
// hàm lấy ra mã trans_confirm_no lớn nhất đang có
SELECT
ttd.trans_confirm_no
FROM
t_transaction_dior ttd
WHERE
ttd.delete_flag = 0
AND ttd.trans_confirm_no LIKE 'JPD%'
AND ttd.trans_status IS NOT NULL
ORDER BY ttd.trans_confirm_no DESC
LIMIT 1;
Vấn đề gặp phải ở đây là khi chúng tôi có nhiều đầu api call đến hàm này cùng thời điểm thì việc tạo ra một mã TMSxxxxx tăng dần gặp vấn đề và nó Generate không đúng với mong muốn.
Khi hệ thống có lượng truy cập lớn, số lượng user mua hàng dồn dập, hàm bên trên sẽ xảy ra trường hợp sinh ra các mã trans_confirm_no trùng nhau.
Sử dụng trigger generate mã trans_confirm_no
// Đầu tiên chúng ta tạo ra 1 bảng để sử cơ chế AUTO_INCREMENT trong mysql để lấy được phần xxxxx nằm trong fomat "TMSxxxxx"
CREATE TABLE transaction_seq
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
// Mình tạo ra 1 trigger sử dụng concat để nối prefix TMS + xxxxx đã được gen ở bảng transaction_seq phía trên.
DELIMITER $$
CREATE TRIGGER tg_t_transaction_dior_insert
BEFORE INSERT ON t_transaction_dior
FOR EACH ROW
BEGIN
INSERT INTO transaction_seq VALUES (NULL);
SET NEW.trans_confirm_no = CONCAT('TMS', LPAD(LAST_INSERT_ID(), 5, '0'));
END$$
DELIMITER ;
// Đặt giá trị bắt đầu AUTO_INCREMENT trong table transaction_seq
ALTER TABLE transaction_seq AUTO_INCREMENT=00001;
Khi sử dụng trigger đã giải quyết được vấn đề của tôi trong bài toán này.
1 comment
Zaproxy dolore alias impedit expedita quisquam.