※本記事は、Bardによる意訳+翻訳を活用し、レイアウト調整したものです。
※感想は、オリジナルです。
原文
Advanced Transaction Management with NestJS & TypeORM | by Muhammet Özen | Medium
意訳+要約
NestJSでトランザクション管理を理解する
NestJSは、Node.jsで構築されたフルスタックフレームワークです。TypeORMは、NestJSでよく使用されるORM(オブジェクトリレーショナルマッピング)ライブラリです。トランザクション管理は、複数のSQLステートメントを単一のユニットとして実行し、エラーが発生した場合にすべてをロールバックするプロセスです。
本記事では、NestJSとTypeORMを使用してトランザクション管理を理解するための基礎を解説します。
トランザクションの基本
トランザクションは、データベースの整合性を維持するために重要です。トランザクションが正常に完了した場合、すべてのSQLステートメントが実行されます。エラーが発生した場合、すべてのステートメントがロールバックされます。
トランザクションは、次の2つの部分で構成されます。
- コミット:トランザクションが正常に完了した場合、コミットによってすべてのSQLステートメントが実行されます。
- ロールバック:エラーが発生した場合、ロールバックによってすべてのステートメントが実行されなくなります。
NestJSとTypeORMでのトランザクション管理
NestJSとTypeORMでは、トランザクションを管理するためのさまざまな方法を提供しています。
トランザクションスコープ
最も簡単な方法は、トランザクションスコープを使用することです。トランザクションスコープは、@Transaction()デコレータを使用して定義します。
@Transaction() async createUser(user: UserDto) { await this.userRepository.save(user); await this.addressRepository.save(user.address); }
コードは慎重に使用してください。詳細
このコードは、createUser()
メソッドをトランザクションスコープで定義しています。このメソッドが正常に完了した場合、両方のリポジトリへの保存がコミットされます。エラーが発生した場合、両方の保存がロールバックされます。
トランザクションマネージャー
トランザクションスコープを使用すると、メソッドのスコープ内でのみトランザクションが有効になります。トランザクションをアプリケーション全体で有効にするには、トランザクションマネージャーを使用します。
トランザクションマネージャーは、@Module()
デコレータを使用して定義します。
@Module({ imports: [ TypeORMModule.forRoot({ // ... }), TransactionManagerModule.forRoot({ // ... }), ], providers: [ // ... TransactionManager, ], }) export class AppModule {}
コードは慎重に使用してください。詳細
トランザクションマネージャーを有効にするには、@UseTransaction()
デコレータを使用してコントローラーまたはサービスに適用します。
@Controller() @UseTransaction() export class UserController { constructor(private readonly userRepository: UserRepository) {} async createUser(user: UserDto) { await this.userRepository.save(user); await this.addressRepository.save(user.address); } }
コードは慎重に使用してください。詳細
このコードは、UserController
コントローラーをトランザクションマネージャーで有効にしています。このコントローラー内のすべてのメソッドは、トランザクションスコープで実行されます。
トランザクションエクスプローラー
トランザクションをさらに細かく制御するには、トランザクションエクスプローラーを使用します。トランザクションエクスプローラーは、@UseTransactional()
デコレータを使用してコントローラーまたはサービスに適用します。
@Controller() @UseTransactional() export class UserController { constructor(private readonly userRepository: UserRepository) {} async createUser(user: UserDto) { await this.userRepository.beginTransaction(); try { await this.userRepository.save(user); await this.addressRepository.save(user.address); await this.userRepository.commitTransaction(); } catch (error) { await this.userRepository.rollbackTransaction(); throw error; } } }
コードは慎重に使用してください。詳細
このコードは、UserController
コントローラーをトランザクションエクスプローラーで有効にしています。このコントローラー内のすべてのメソッドは、トランザクションスコープで実行されます。また、メソッド内でトランザクションを開始、コミット、またはロールバックできます。
Bardさんに聞いてみた
Q:TypeORMは、Springに近い記述方法でトランザクション管理を行うのでしょうか?
基本的には近いです。
TypeORMでは、トランザクションを管理するための3つの方法を提供しています。
このうち、トランザクションスコープは、Springの@Transactional
アノテーションに相当します。トランザクションスコープを使用すると、メソッドのスコープ内でのみトランザクションが有効になります。
トランザクションマネージャーは、Springの@EnableTransactionManagementアノテーションに相当します。トランザクションマネージャーを使用すると、アプリケーション全体でトランザクションが有効になります。
トランザクションエクスプローラーは、Springの@Transactionalアノテーションと@EnableTransactionManagementアノテーションを組み合わせた機能です。トランザクションエクスプローラーを使用すると、トランザクションをさらに細かく制御できます。
Q:TypeORMは、Springの影響を受けているのでしょうか?
はい、TypeORMはSpringの影響を受けています。
TypeORMのトランザクション管理は、Springのトランザクション管理と基本的な概念は同じです。トランザクションスコープ、トランザクションマネージャー、トランザクションエクスプローラーの3つの方法を提供しており、Springの@Transactional
アノテーション、@EnableTransactionManagement
アノテーション、@Transactional
デコレータと似ています。
また、TypeORMの開発者は、Springの開発者であるRod Johnson氏と協力しています。Rod Johnson氏は、TypeORMのトランザクション管理の設計にも関わっています。
このように、TypeORMはSpringの影響を強く受けており、Springの開発者との協力によって開発されています。
なお、TypeORMはSpringの影響を受けている一方で、独自の機能も備えています。たとえば、TypeORMは、トランザクションの分離レベルを指定できる機能や、トランザクションのロールバック時に、コミット済みのステートメントをロールバックできる機能を備えています。
感想+雑記
Springを使っている身からすると、コードはだいぶ分かりやすかった。
TypeScriptは、個人開発のフロントエンドで使っているが、バックエンドでもイケそうだなって感じてきた。
まぁ、バックエンドの処理をどこで書くのかだろうな。。。
Next.jsやElectronなら、フロントエンドだとしても使いそう。
型づけが強力だから、利用想定は、RDBだろうな。
NoSQLでの利用想定はあるのだろうか?
最近、TypeORMを知ったので、興味を持って要約を見ることができた。
ORマッパーとしてではなく、トランザクション管理もできるんだな。