Open棟梁 wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

データアクセス関連の処理方式についてまとめる。

コネクション & トランザクション管理

コネクション管理方式

ConnectionのOpen/Close

ConnectionのOpen/Close処理の実装は、”Open棟梁”のB層の「ベースクラス2」(業務コード親クラス2)上に共通処理として実装できる。

Connection Pooling

コネクション プーリングに関しては、通常データ プロバイダが保有するコネクション プーリング機能をそのまま使用する。

トランザクション制御方式

自動トランザクション

手動トランザクション

1回のB層呼び出しに対して、複数のコネクション、トランザクションが必要となる要件が発生した場合は、
手動トランザクションを検討する(”Open棟梁”は手動トランザクションもサポートしている)。

サンプル・コード

必要とする場合など、

トランザクション、コネクションの解放処理(CommitTransactionConnectionCloseメソッド)には、try...catch...finallyを使用しても良いが、
通常GCにより解放される場合、トランザクションはロールバックされ、コネクションも切断される(若しくは接続プールに戻される)。

排他制御方式

HTTPリクエストなど、通信処理(リクエスト)を跨いだ排他制御方式については、
通信処理(リクエスト)を跨いでDBMSトランザクションを持続できないので、
リクエストを跨いで排他(ロック)を掛けるには、楽観排他方式悲観排他方式を採用する。

DBMSトランザクションの範囲の排他制御方式

DBMSトランザクションの範囲は、DBMSの分離レベルに従った排他制御の動作を理解し、
必要に応じて更新ロック(OracleであればFor Update Wait・NoWait?、SQLServerであればWith (UpdLock?))など、個別にロックを適用する 。

楽観排他方式

全列比較方式

.NETでは、DataTable?がサポートするDataRowVersion?を使用した楽観方式

が一般的であるが、クエリが無用に長くなる等の問題もあるのでタイムスタンプ方式を推奨する。

タイムスタンプ方式

楽観排他方式(タイムスタンプを使用する)は、

排他方式である。

タイムスタンプ

SQL ServerやOracleにはタイムスタンプ型がある。

D層自動生成ツール

なお、”Open棟梁”のD層自動生成ツールでは、

楽観排他(ロック)対応のDao生成が可能で、

などが可能である。

悲観排他方式(ロック管理テーブル)

以下のケースで、ロック管理テーブルなどを使用して悲観排他を実現する。

行単位の悲観排他(ロック)を必要とするテーブル毎に「行ロック管理テーブル」を用意しておく。

行ロック管理テーブル

「行ロック管理テーブル」は次のように設計すると良い。

キー(ユニーク)ロック ユーザロック取得時間
aaaUser1yyyy/MM/dd HH:mm:ss.SSS
bbbUser2yyyy/MM/dd HH:mm:ss.SSS
cccUser3yyyy/MM/dd HH:mm:ss.SSS

処理シーケンス

行単位の悲観排他(ロック)方式の処理シーケンスを以下に示す。

  1. トランザクションを開始して更新先テーブルを参照し、更新ロックをかけた状態で更新対象データ行を取得する。
  2. 同一トランザクション内で「行ロック管理テーブル」に、上記の更新対象データ行の主キーを追加する。
    追加の際、主キーは「キー(ユニーク)」列へ、ユーザ名は「ロック ユーザ」列へセットする。
    • 追加に失敗した場合は、悲観排他(ロック)取得に失敗したものとし、処理を中断する。
    • 追加に成功した場合は、悲観排他(ロック)取得に成功したものとし、処理を続行する(トランザクションをコミット)。
  3. 取得した更新対象データ行をクライアントにレスポンス、画面に表示し、編集処理を行う。
  4. トランザクションを開始して
    • 更新先テーブルを参照し、更新ロックをかける。
    • 「行ロック管理テーブル」の更新対象データに対応するレコードを参照し、更新ロックをかける。
  5. 上記の2つのレコードのうち、
    • どちらか一方 or 双方が存在しない場合は、処理に失敗したものとし、処理を中断する。
    • 双方が存在する場合は、処理に成功したものとし、処理を続行する。
  6. 「行ロック管理テーブル」に更新ロックをかけた状態で、更新対象データ行の更新を行う。
  7. 同一トランザクション内で「行ロック管理テーブル」のレコードを削除する(トランザクションをコミット) 。

テーブル設計

コード設計

コードには以下の種類がある。

採番コード

リストコード

削除方式

物理削除か?論理削除か?を検討する。

物理削除

論理削除

データのアーカイブ方法

増え続けるトランザクションデータは性能やメンテナンス上の問題を引き起こすため、データのアーカイブ方法を検討しておく。

マスタ・データ

有効期限付きデータを利用する場合

システム共通定数テーブル

(有効期限付きデータの併用可能)。

ID採番方式

SEQUENCE・IDENTITY

必ず、連番にならなくても良ければ、
DBMSに実装されているSEQUENCEやIDENTITYを使用する。

以下、主要DBMSの採番機構を表に纏めた。

項番DBMS採番機構確認方法
1OracleSEQUENCEオブジェクトSEQUENCE.CURRVALを確認する。
2SQL Serverオート インクリメント列(IDENTITYプロパティ)INSERTに続けてSCOPE_IDENTITYを確認する。
INSERT xxx(…) VALUES(…); SELECT SCOPE_IDENTITY ();
※ パラメタライズド・クエリではsp_executesql経由で実行されるので別のスコープで実行される。
このため、上記の様に、INSERTとSELECTを連続して記述する必要がある。
3DB2SEQUENCEオブジェクト・・・
4MySQLオート インクリメント列(AUTO_INCREMENT属性)・・・
5PostgreSQLSEQUENCEオブジェクト・・・
6HiRDBSEQUENCEオブジェクト・・・

Windows Server 2008 R2から、SEQUENCEオブジェクトがサポートされたらしい。

連番採番方式

必ず連番にする連番採番方式は、要件に合わせて個別に設計する。

レコード更新履歴の記録

”Open棟梁”では直接サポートしていないが、
ベースクラス2」(データアクセス親クラス2)上に共通処理を実装できる。

方式は色々あるので、プロジェクト毎に方式を決めること。

履歴情報

全テーブル共通項目などを用意して、

の情報を保持するなど(このような処理はDaoで共通化できる)。

SQL(DML)の記録

プロジェクト対応で、「ベースクラス2」(データアクセス親クラス2)上にSQLトレース ログをDB上に出力する共通処理などを実装したケースはある。

更新前データの記録

また、DBMSのトリガを使用することで更新前のデータを別テーブルに記録することもできる。

データアクセス標準化

CRUD図

デッドロック防止

DBMS側機能の使用

デメリット

DBMS側機能を使用すると

ストアド・プロシージャ

データアクセス速度が速いので大量データの処理がある場合は使用を検討する。

トリガ

トリガのイベントドリブンの問題

イベントドリブンでの頻繁なデータアクセスにより、
パフォーマンス・保守性の低下、トリガ連鎖のリスクがある。

外部参照制約

データのインサートやデリートの処理順番を考慮する必要がある。

SQL CLR

大量データの処理

参考:大量データの処理

結果セットの肥大化の軽減

SQLの「SELECT * FROM]を使用しない。

必要なカラムの射影を取得するようにする。

一覧ページ制御方式

ページングにより結果セットを分割する。

ラウンドトリップの軽減

イテレータの様に主キーでのDBアクセスをしない

プログラムでデータを結合しない

その他、PG <---> DB間のラウンドトリップを防止

バッチ処理方式

前述の

を考慮した実装を行う。

大量データの取扱

DataSet、DataTableを使用したバッチ更新方式

性能を考慮した動的パラメタライズド・クエリの連続実行方法

オンラインバッチ

複数DBMSサポート方式

Dam Factory

「業務コード親クラス2」のコネクション接続メソッド(MyBaseLogic?.UOC_ConnectionOpen)に
GoFデザインパターンのFactory Method パターン的にデータ アクセス制御クラス(Dam) を
DBMS(データプロバイダ)毎に用意された指定の型で選択的に生成・保持する処理を実装する。

なお、このコネクション接続メソッドでは、

の処理を実装する。

以降の処理ではDamをベースの型で扱うようにして
DBMS(データプロバイダ)固有型(機能)の使用を局所化する必要がある。

DBMS排他制御

トランザクション制御方式」の「排他制御方式」を検討しておく。

レコード更新履歴の記録

レコード更新履歴の記録」の方法を検討しておく。

ID採番方式

ID採番方式」の方法を検討しておく。

一覧ページ制御方式

一覧ページ制御方式」の方法を検討しておく。

.NET型とDBMS型のマッピング

引数と戻り値に既定の型のマッピング(.NET型 <---> DB型)がある。

トラブルシュート

SQLで暗黙の型変換が発生し、検索処理性能が大幅に劣化する。

概要

対策例

以下に、パラメタライズド・クエリを使用して、AAAテーブルのBBBカラム(varchar型、インデックス作成済み)に対して、
@P1パラメタの検索条件を指定した際に発生した「暗黙の型変換」による性能劣化 ~ 対策の事例を示す(SQL Serverでの事例)。

補足

各DBMSの変換関数を仕掛けたパラメタを必要な数だけ埋め込むようにして対処するようにする。

SQL Server 大量データ処理時の性能問題

その他

D層(Dao)毎のデータアクセス例

動的パラメタライズド・クエリとEF・Dapperの使い分けについて。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS