在此场景中,SQL事务用于将数据插入到三个表中:Customer、Order和OrderItem.预期的行为是,如果事务中的任何查询失败,整个事务都应该回滚,以确保数据一致性.但是,事务似乎没有按预期的方式运行,因为当后续查询遇到错误并且无法将数据插入表时,事务不会回滚.

import { Request, Response } from 'express';
import { Order }  from "../models/order.model";
import IResponse from "../interfaces/response.interface";
import { CustomerModel  } from '../models/customer.model';
import db from '../database';
import { OrderItems } from '../models/orderitem.models';
import ProductModel from '../models/product.model';

class OrderController {
async createOrder(req: Request, res: Response): Promise<void> {
    interface Product {
        product_id: number;
        name: string;
        quantity: number;
        price: number;
    }

    try {
        const { products, name, email, phone, address } = req.body;
        let totalPrice = 0;
          // Calculate total price
          products.forEach((product: Product) => {
            const subtotal = product.quantity * product.price;
            totalPrice += subtotal;
        });
        const result = await db.transaction(async (t) => {
            // Create customer
            const customer = await CustomerModel.create({
                name: name,
                email: email,
                phone: phone,
                address: address,
                transaction: t // Assign transaction
            });
            const cust_id = customer.customer_id;

            // Create order
            const order = await Order.create({
                customer_id: cust_id,
                total_amount: totalPrice,
                order_date: new Date(),
                created_by: '1',
                transaction: t // Assign transaction
            });
            const order_id = order.order_id;

            // Create order items
            const orderItemsPromises: Promise<void>[] = products.map((product: Product) => {
                return OrderItems.create({
                    order_id: order_id,
                    product_id: product.product_id,
                    order_date: new Date(),
                    quantity: product.quantity,
                    price: product.price,
                    transaction: t // Assign transaction
                });
            });

            // Wait for all order items to be created
            await Promise.all(orderItemsPromises);

            return order; // Return the order created within the transaction
        });
        res.status(201).json({ message: 'Order created successfully' });
    } catch (error: any) {
        // Send error response
        console.error(error);
        const response: IResponse = {
            statusCode: 500,
            status: 'error',
            message: error.message,
            data: '',
        };
        res.status(500).json(response);
    }
}
}

在sqquelize文档和try 的托管事务中,把事务中涉及的所有查询都封装在事务块中.这确保了如果任何查询失败,整个事务都会回滚.但它并没有像预期的那样工作?

推荐答案

const customer = await CustomerModel.create({
    name: name,
    email: email,
    phone: phone,
    address: address,
    transaction: t // Incorrectly included in the data object
});

读取"Sequelize Transactions"时,事务对象应该作为选项对象的一部分传递,而不是在正在创建或更新的数据对象中传递.

您需要每个Sequelize操作(在本例中为create)将事务(t)从数据对象移动到选项对象(create方法的第二个参数):

const customer = await CustomerModel.create({
  name: name,
  email: email,
  phone: phone,
  address: address,
}, { transaction: t }); // Correctly pass transaction here

订购:

const order = await Order.create({
  customer_id: cust_id,
  total_amount: totalPrice,
  order_date: new Date(),
  created_by: '1',
}, { transaction: t });

订单项目:

const orderItemsPromises = products.map((product: Product) => {
  return OrderItems.create({
    order_id: order_id,
    product_id: product.product_id,
    quantity: product.quantity,
    price: product.price,
  }, { transaction: t });
});

Node.js相关问答推荐

在child_Process中持久运行SSH命令

自动将Selify打开的Chrome窗口移动到Mac OS中的第三个显示器

为什么在导出的函数中调用node-sqlite3中的数据库方法时不起作用?

模块';"; node :流程&没有导出的成员';dlopen';

ForbidenError:使用Express.js的CSRF令牌无效

在全局对象上声明的函数

mongoose 7.0.3 使用运算符 $and 严格搜索日期

使用 fs.createWriteStream 将数据写入 bigquery (node.js) 时出现模式错误

在快速路由中使用 axios 会在数据字段中返回特殊字符而不是 json

node Axios 创建全局令牌变量以在单独的变量头中使用

为什么当我try req.logout() 时出现此错误?

如何在 TypeScript 中输出 Hackerrank 二叉树问题?

如何使动态私有IP地址静态?

如何申请在NextJS上下载文件的许可?

如何使用 superagent/supertest 链接 http 调用?

名称类型为 mongoose 的字段

如何忽略文件 grunt uglify

要求('babel/register')不起作用

Mongoose:模式与模型?

Firestore:多个条件 where 子句