DOBON.NET DOBON.NETプログラミング掲示板過去ログ

排他制御について

環境/言語:[.Net Framework 2.0]
分類:[ASP.NET]

排他制御を行おうと思っているのですが、思い通りの動きを作成できなくて
困っております。
何か良い方法があれば、ご教授頂けないでしょうか。


ASP.Netにて更新画面があるが、画面表示を行った時点で利用するテーブル
全ての対象データに行ロックをかけたいと思っています。

排他制御をかける際、データ量も多く更新プログラムも複雑なため、排他制御を
かける行は、細かい条件は抜きにして、メインのキー情報のみでロックをかけたい。
※画面表示〜画面で値の編集〜更新実行の間、常にロックをかけ、ロックがかかっている
 データは他ユーザから閲覧もできなくする。
 つまり、画面表示の時点でFOR UPDATE句を利用して排他制御をかける。

  1 Dim dt As DataTable = New DataTable()
  2 Using con As New OracleConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ToString())
  3  Using cmd As New OracleCommand(strSQL, con)
  4   Using adp As New OracleDataAdapter(cmd)
  5    con.Open()
  6    cmd.CommandType = CommandType.Text
  7    adp.Fill(dt)
  8   End Using
  9  End Using
 10 End Using

ロックをかける部分はSELECT文にFOR UPDATE句をつけるだけで単純にいけるので
問題ないのですが、画面で値を編集して更新を行った際、OracleCommand.Transactionを
利用して更新を行っています。

  1 Dim dt As DataTable = New DataTable()
  2 Using con As New OracleConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ToString())
  3  Using cmd As New OracleCommand(strSQL, con)
  4   Using adp As New OracleDataAdapter(cmd)
  5    con.Open()
  6    cmd.CommandType = CommandType.Text
  7    cmd.Transaction = cmd.Connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted)
  8    adp.Fill(dt)
  9    cmd.Transaction.Commit()
 10   End Using
 11  End Using
 12 End Using

この時、7行目で下記のようなエラーが発生してしまいます。

ORA-01453: SET TRANSACTIONはトランザクションの最初の文である必要があります

ロックをかけてから画面に一旦戻っているため、当然最初のコマンド(画面表示用検索時点)は有効でないため、
ロックバックorコミットを行ってから更新処理に入ることもできません。

どのように対処したら良いのでしょうか。
宜しくお願いいたします。
■No22020に返信(celestiaさんの記事)

すみません、質問内容とは違いますが、

私は画面入力による排他制御は、
更新読込時に更新情報(更新日時など)を読みこみ
更新時に、読込時に更新情報と最新の更新情報が
違うかどうかで判断してたりします。
同じなら更新し違うなら更新エラーで読み直し
としています。

実用的な排他
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9904/lock/
  • 題名: Re[2]: 排他制御について
  • 著者: celestia
  • 日時: 2008/05/13 20:18:15
  • ID: 22022
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
> 更新読込時に更新情報(更新日時など)を読みこみ
> 更新時に、読込時に更新情報と最新の更新情報が
> 違うかどうかで判断してたりします。
> 同じなら更新し違うなら更新エラーで読み直し
> としています。

私も基本的にその考え方で排他制御を行っているのですが、今回の場合は
ロック対象のレコード件数が多いため、キー情報だけで排他制御ができないか
模索しておりました。

そのキー情報に該当するレコード(対象テーブル全て)に対し、更新情報で
チェックをすれば可能なのはわかっておりますが、もう少し簡単に制御が
できないのではと思い質問させて頂きました。

DOBON.NET | プログラミング道 | プログラミング掲示板