Open棟梁 wiki

目次

概要

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

コネクション管理方式

ConnectionのOpen/Close

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

Connection Pooling

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

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

自動トランザクション

手動トランザクション

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

排他制御方式

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の「SELECT * FROM]を使用しない。

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

一覧ページ制御方式

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

ラウンドトリップの軽減

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

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

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

ストアドプロシージャ、SQL CLRなどを使用する。

複数DBMSサポート方式

Dam Factory

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

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

の処理を実装する。

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

DBMS排他制御

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

レコード更新履歴の記録

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

ID採番方式

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

一覧ページ制御方式

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

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

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


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