프리스마2의transaction 질문을 Active Record 스타일로 쓰고 싶어요.
24122 단어 JavaScriptNode.jsSQLPrismatech
※ mysql2의 예.
import * as mysql2 from 'mysql2/promise';
const db = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'test'
});
await db.begin();
if(//何らかのロジック処理) {
//何らかのデータベースアクセス
await db.commit();
} else {
await db.rollback();
}
만약 이것이 Prism이라면 현 버전 3.2.1은 안 된다.대체로 공식적으로 몇 가지 거래 방법이 있다.( transactions )
Primse.All
에 배열된 데이터 접근 처리를 실행하고 그 중 하나가 실패하면 다른 접근도 굴러갑니다.
const [posts, totalPosts] = await prisma.$transaction([
prisma.post.findMany({ where: { title: { contains: 'prisma' } } }),
prisma.post.count(),
])
그 배열에prisma 이외의 상업 논리를 넣으면 안 되는 것과 (틀릴 가능성도 있다) 첫 번째 성공한 값은 두 번째Promise
에서 사용할 때 복잡해진다.그리고 하나는 관련 표에 데이터를 동시에 입력하는 거예요.
// Create a new user with two posts in a
// single transaction
const newUser: User = await prisma.user.create({
data: {
email: '[email protected]',
posts: {
create: [
{ title: 'Join the Prisma Slack on https://slack.prisma.io' },
{ title: 'Follow @prisma on Twitter' },
],
},
},
})
이것도 내가 직면한 문제를 해결할 수 없다.다만, 버전 2.29.0에서 「Interactive Transactions」까지의 미리보기 기능이 설치된 것 같습니다.👇이렇게 쓰면
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function transfer(from: string, to: string, amount: number) {
return await prisma.$transaction(async (prisma) => {
// 1. Decrement amount from the sender.
const sender = await prisma.account.update({
data: {
balance: {
decrement: amount,
},
},
where: {
email: from,
},
})
// 2. Verify that the sender's balance didn't go below zero.
if (sender.balance < 0) {
throw new Error(`${from} doesn't have enough to send ${amount}`)
}
// 3. Increment the recipient's balance by amount
const recipient = prisma.account.update({
data: {
balance: {
increment: amount,
},
},
where: {
email: to,
},
})
return recipient
})
}
async function main() {
// This transfer is successful
await transfer('[email protected]', '[email protected]', 100)
// This transfer fails because Alice doesn't have enough funds in her account
await transfer('[email protected]', '[email protected]', 100)
}
main()
.catch(console.error)
.finally(() => {
prisma.$disconnect()
})
우선 ASync function에서 예외가 발생한 경우 롤백이 자동으로 뛰는 것 같아서 괜찮은 것 같다.미리 보기 기능이기 때문에
prisma.schema
을 사용하려면 파일에 설명을 추가해야 합니다.prisma.schema
generator client {
provider = "prisma-client-js"
previewFeatures = ["interactiveTransactions"]
}
상관은 없지만 거래하는 동안 모델의 함수로 컨트롤러로부터 거래를 하면서 사업 논리와 다른 처리를 하고 싶어서 제가 직접 포장을 해서 적어보려고요.userModel.ts
//...省略...
async createUser(
user: User,
callback?: (newUser?: User) => Promise<void>,
): Promise<User> {
const createNewUser = (db?: PrismaTransactionCallBackInstance) => {
const connection = db || this.db;
return connection.user.create({
data: {
...user
},
select: {
email: true,
id: true,
},
});
};
try {
if (callback && typeof callback === 'function') {
const resultUser = await this.db.$transaction(async (db) => {
const result = await createNewUser(db);
await callback(result);
return result;
});
} else {
const resultUser = await createNewUser();
}
return resultUser;
} catch (error) {
throw error;
}
}
//...省略...
authController.ts //...省略...
async signUp() {
try {
//承認用のランダムの文字列作成
const confirmationCode = this.authService.generateConfirmationCode();
//userオブジェクト作成
const user = new User({//user情報登録});
//usecaseの呼び出し
await this.userModel.createUser(user, async (newUser: User) => {
//承認メールの送信
await this.mailer.sendVerification({
email: newUser.email,
confirmationCode,
});
});
return 'success';
} catch (error) {
console.log('outside catch');
throw error;
}
}
//...省略...
이렇게 하면 메일을 모델에 보내지 않고 실행할 수 있다.
Reference
이 문제에 관하여(프리스마2의transaction 질문을 Active Record 스타일로 쓰고 싶어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/qaynam/articles/0ef7c4d28a9066텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)