- PR -

待ち状態を発生させたい

1
投稿者投稿内容
MIRU
常連さん
会議室デビュー日: 2006/05/30
投稿数: 21
投稿日時: 2007-09-21 19:45
現在下記の環境にて、Webアプリケーションの作成を行なっております。

#VB.NET2003 (Framework1.1)
#Oracle 9.2.0 (ODP.NETで接続)

クライアント2台で同一レコードに同時に更新処理を行なおうとした場合、
片方の端末でエラーが発生し困っております。

1台目の処理でレコードにロックをかけているため、
2台目でエラーが発生しているようなのですが、
2台目の処理をロックが解除されるまで待ち状態にすることにはどうするればよいでしょうか?

以下に使用しているコードを記述しておきます。
ORAstr() ・・・ 更新SQLの命令文の配列
counter ・・・ 更新SQL配列の件数
------------------------------------------------------------------------------
Public Function inBySQL(ByVal ORAstr() As String, ByVal counter As Integer) As String
Dim i As Integer
Dim cnnin As New OracleConnection
Dim txnin As OracleTransaction
cnnin.ConnectionString = "User Id=AAA; Password=BBB; Data Source=CCC"
cnnin.Open()
Try
txnin = cnnin.BeginTransaction(IsolationLevel.Serializable)

Dim cmd As New OracleCommand
cmd.Connection = cnnin

For i = 0 To counter - 1
If Not (ORAstr(i) Is Nothing) Then
cmd.CommandText = ORAstr(i)
cmd.ExecuteNonQuery()
End If
Next

txnin.Commit()
cnnin.Close()
cnnin.Dispose()
Return ("")
Catch ex As Exception
txnin.Rollback()
cnnin.Close()
cnnin.Dispose()
Return (i & "行目 エラー発生")
End Try
End Function
------------------------------------------------------------------------------
上記は、複数の更新処理を一つのトラントランザクションで行ないたいために
配列としております。


どなたかご教授お願いします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-09-21 21:14
引用:

MIRUさんの書き込み (2007-09-21 19:45) より:
クライアント2台で同一レコードに同時に更新処理を行なおうとした場合、
片方の端末でエラーが発生し困っております。


発生しているエラーを書きましょう。
他の人には何が起こっているかわかりません。

引用:

txnin = cnnin.BeginTransaction(IsolationLevel.Serializable)


隔離レベルがSerializableなので、起こっているエラーは
ORA-08177: can't serialize access for this transaction
だと思います。

この場合は、更新を行おうとしている行を事前にSELECT FOR UPDATEしましょう。
OracleはSerializableの場合に、Phantom readの回避をロックではなく、
トランザクションを失敗させて対処します。
MIRU
常連さん
会議室デビュー日: 2006/05/30
投稿数: 21
投稿日時: 2007-09-25 13:27
返信が遅くなり、申し訳ありません。
あしゅさんが指摘されたとおりエラーはORA-08177でした。


トランザクション開始
 SELECT FOR UPDATE
UPDATE 〜〜
トランザクション終了

とすることによって、正常に登録が行なえました。

ありがとうございました!
1

スキルアップ/キャリアアップ(JOB@IT)