初めに
TypeORMを使用してDB操作を実装しているときに、「あっ、エラーが発生した時のロールバック処理も実装しないと」と思い、実装したプログラムを紹介します。
環境
- Windows10
- typeorm 0.2.34
- typescript 4.3.2
- node 14.17.0
- Azure Database for MySQL サーバー
コード
Entityファイル
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity("crawler_history")
export class CrawlerHistory {
@PrimaryGeneratedColumn()
readonly id?: number
@Column("varchar", { name: "status", length: 30 })
status!: string
@Column("text", { name: "message" })
message!: string
@Column("datetime", { name: "create_date" })
createDate!: string
}
メインファイル
1ファイルで紹介したかったため1ファイルにすべて詰め込んでありますが、
適宜管理しやすいようにファイルを分けたほうがいいと思います。
import { createConnection, EntityManager, getManager } from "typeorm";
import fs from 'fs'
import { CrawlerHistory } from "./entity/CrawlerHistory";
//IIFE 即時関数
(async function main() {
//db接続
const connection = await createConnection({
type: "mysql",//※1
host: "{your host}",
port: 3306,
username: "{your user}",
password: "{your password}",
database: "{your database}",
synchronize: false,
ssl: { ca: fs.readFileSync('./ssl/DigiBalRoot.crt.pem') },//※2
logging: false,
entities: ["entity/**/*.js"],//※3
migrations: ["migration/**/*.js"],
subscribers: ["subscriber/**/*.js"],
cli: {
entitiesDir: 'entity',//※3
migrationsDir: 'migration',
subscribersDir: 'subscriber',
}
}).catch(err => { throw err; })
if (connection) {//接続の確立
console.log('connection open')
await getManager().transaction(async (transactionalEntityManager) => {//※4
await createCrawler_history({
status: 'INFO',
message: '登録しました',
createDate: new Date().toISOString()
}, transactionalEntityManager).then(() => console.log('登録'))
}).catch(async () => {//※7
console.log('ロールバックの実行')
})
} else {
console.log('接続が失敗しました。')
}
await connection.close()//※5
console.log('connection close')
})()
const createCrawler_history = async (body: CrawlerHistory, transactionalEntityManager: EntityManager) => {
//DB接続
await transactionalEntityManager.save(CrawlerHistory, body)
throw new Error //※6
}
-
※1
今回使用するDBがmysqlのためmysql
とします。
波括弧{}で囲われた部分は使用するDBの情報に置き換えてください。 -
※2
AzureDBの設定で接続のセキュリティ項目にて、SSL接続を強制にするを有効にしているとpemファイルが必要になります。
保存したpemファイルのパスに置き換えてください。
今回の例ではindex.ts直下にsslフォルダを作成しその中に保存しました。 -
※3
entityのファイルを作成した場所のパスです。 -
※4
トランザクション処理です。
今回は1つしか実行していないが、この内部に書かれた関数内で例外が発生すると、実行していた SQL がロールバックされる。 -
※5
接続の切断メソッドです。 -
※6
今回の例ではこの場所でErrorを出している。
正常に動かす場合はこの行をコメントアウトする。 -
※7
DBに関するものしかロールバックされないため、前に別の処理を行っていた場合はここでその処理についてロールバックする必要がある。
例:私の場合はIBMCloudのDiscoveryに文書を登録し、
そのあとに実行ログを残していたため、登録した文書を削除する処理を記述しました。
終わりに
TypeOrmはまだまだできることが多いので調べつつ、またいろいろ記事にしていけたらと思います!