- PR -

DBがAS400の場合、DB更新すると「同時実行違反」が発生する

1
投稿者投稿内容
みりゅ
会議室デビュー日: 2005/05/19
投稿数: 2
投稿日時: 2005-05-19 10:18
現在、VB.NET + DB(AS400) でWindowsApplicationをの開発をしています。

フォームにDataGrid1、Button1、Button2を配置して以下のソースで実行。
フォーム起動後、Button1をクリックし、
DataGrid1に表示されたデータを直接編集後、Button2をクリック
ConnectStringBuildがAS400の場合
・Insert -------> 成功
・InsertしたレコードのUpdate -------> 成功
・InsertしたレコードのDelete -------> 成功
・既存データのUpdate -------> 失敗
メッセージ「同時実行違反:UpdateCommandによって0件処理されました。」
・既存データのDelete -------> 失敗
メッセージ「同時実行違反:DeleteCommandによって0件処理されました。」
ConnectStringBuildがAccessの場合
・Insert -------> 成功
・InsertしたレコードのUpdate -------> 成功
・InsertしたレコードのDelete -------> 成功
・既存データのUpdate -------> 成功
・既存データのDelete -------> 成功

以下ソースです。
'/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/
Imports System.Data.OleDb
Public Class frmDBTest
Inherits System.Windows.Forms.Form

Private oleDA As OleDbDataAdapter
Private oleCB As OleDbCommandBuilder
Private ds As DataSet
'AS400の場合
Const strConnectStringBuild As String = _
"Provider=IBMDA400;Default Collection=TEST#DB;Data Source=****;" & _
"User ID=QSECOFR;Password=QSECOFR;Force Translate=65535"
'Accessの場合
'Const strConnectStringBuild As String = _
"Provider=MICROSOFT.JET.OLEDB.4.0;Data Source=C:\TestDB.mdb;" & _
"Persist Security Info = false"
Const strSQL As String = "SELECT * FROM TESTTBL"

'・・・・
'+ Windows フォーム デザイナで生成されたコード
'・・・・

'非接続型データ取得とDataGridへデータセット
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Me.ds = New DataSet("MyDataSet")
oleDA = New OleDbDataAdapter(strSQL, strConnectStringBuild)
oleCB = New OleDbCommandBuilder(oleDA)
oleDA.Fill(ds, "MyDataTable")
Me.DataGrid1.DataSource = ds.Tables(0)

End Sub

'非接続データを使ってDB更新
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Try
'ソース内で作成アダブタを使用
Me.oleDA.Update(ds, "MyDataTable")
MsgBox("更新成功")
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical Or MsgBoxStyle.OKOnly)
End Try
End Sub
End Class
'/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/
以上、AS400で同時実行違反が発生しないようにするにはどうすればいいのか
もし何かお分かりになる方がいらっしゃいましたら宜しくお願いいたします。
atok
常連さん
会議室デビュー日: 2004/05/11
投稿数: 32
お住まい・勤務地: TOKYO
投稿日時: 2005-05-19 13:05
こんにちわ。

WindowsApplicationの方は、只今勉強中なので
的外れな事かも知れませんが、関係ありそうなサイトを見つけたので
書き込みをさせてもらいました。

[msdn JAPAN:同時実行エラーの処理]
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcon/html/vbtskcatchingconcurrencyerror.asp
(既に参照済みでしたら、ごめんなさい。)

1つ気になったのですがよろしいですか?
「OdbcDataAdapter」ではなくて「OleDbDataAdapter」を利用されているのには、
 何か理由があるのでしょうか?
(私は「OdbcDataAdapter」しか使用したことが無いのでメリット等があるのであれば教えて欲しいです。)
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-19 13:42
引用:

以上、AS400で同時実行違反が発生しないようにするにはどうすればいいのかもし何かお分かりになる方がいらっしゃいましたら宜しくお願いいたします。


 ソースを貼り付けていることから、調べもしないで聞いていると判断します。同時実行違反(DBConcurrencyException)がどういうもので、どういう時に発生するのか、調べてください。

 そうすると、ソースを貼り付けるのは無駄なことで、別のものを提示しなければないけないことがわかります。

 だいたい、同じソースでデータベースを換えればエラーになるなら、ソースよりもデータベースの設定を疑うのでは???
 MSDNを検索すれば、こんなのもあるし。
 @ITで調べるだけでも、答えは出ているのに。

 「いや、調べたけどわからなかったのだ」とおっしゃるなら、何をどう調べてどんな結果を得、そこからどう判断したのか、教えてください。

_________________
みりゅ
会議室デビュー日: 2005/05/19
投稿数: 2
投稿日時: 2005-05-23 09:30
atokさん、Jittaさん
遅くなりましたがご返答ありがとうございました。

atokさん、
> 「OdbcDataAdapter」ではなくて「OleDbDataAdapter」を利用されているのには、
>  何か理由があるのでしょうか?
現場の方針で、特に理由はわかりません。
答えにならず、すみません。

Jittaさん
> ・・・・ソースよりもデータベースの設定を疑うのでは???
そうは思ったのですが、AS400については詳しくないこともあり
もしかするとソース側でなにかあるのでは・・・と思いまして。

後から、分かったことなのですが、DB側の既存レコードで
改行コードを含むフィールドの改行コードを取除いたら
問題なく更新できたそうです。
それでもソース側でどうしたらよいか
確かな原因がわからずじまいで、結局"CommandBuilder"を
使わない方法でやることになりました。
katope
会議室デビュー日: 2003/01/24
投稿数: 5
お住まい・勤務地: 名古屋の隣
投稿日時: 2005-05-23 14:36
別方法で実施されるとの事で、解決済かと思いますが・・・。

私のところでは、AS400との接続では、データ連結を使用しないで処理してきました。
連結すると、データ更新がうまくいかなかったからです。

最近ClientAccessのサービスパックを当てたので、みりゅさんのソースを実験してみました。
Verは5.2.0 SI16915です。

当方では、追加・更新・削除とも、みりゅさんのソースで問題なく動きました。
もし、最新のサービスパックを当てられてないのなら、一度試してみてはいかがでしょうか。

#AS400の場合は、例外の内容が必ずしも実際の不具合の内容と一致しない場合があるので
「ソース掲載=調べてない」と判断するのは早計かも
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-23 21:38
引用:

後から、分かったことなのですが、DB側の既存レコードで改行コードを含むフィールドの改行コードを取除いたら問題なく更新できたそうです。
それでもソース側でどうしたらよいか確かな原因がわからずじまいで、結局"CommandBuilder"を使わない方法でやることになりました。


 それは1つの“良い”解決策ですが、原因を突き詰めないで、本当に良いのですか?
 または、原因がわからないのになぜ「CommandBuilderを使わない」と決めたのでしょう?

 例えば、私が@ITでの検索結果を出していますが、そこにある「sqlExceptionとDBConcurrencyExceptionについて」を見ていただくと、DBConcurrencyExceptionがどの様なときに発生するか、どの様なエラーか、書いています。
 つまり、更新対象が1つもないときに発生する例外です。CommandBuilderを使用すると、全列一致検索をします。すべての列が一致するレコードを探すので、すべての列にインデックスが貼られていないと全件検査となるため、非常に効率が悪いことになります。肝心な、データバインドの箇所が無いのでどの様にバインドしていたのかわかりませんが、AccessとAS400とで、“空白コード”の扱いが違うか、入っているデータが違っていた(Accessでは改行コードが取り除かれていた)ことが考えられます。


katopeさん>
引用:

#AS400の場合は、例外の内容が必ずしも実際の不具合の内容と一致しない場合があるので
「ソース掲載=調べてない」と判断するのは早計かも


 上にも書いていますが、この例外は「更新の対象がなかった」為にでるものなので、データベースが出すものじゃないんですよ。つまり、データベースそのものの設定か、SQL文、パラメータの連結のさせ方、データ、に原因があるわけです。ソースに原因があるとしても、データベース接続や更新を行う外側(DataAdatapter.Updateの前後)に原因があることは、まずありません。つまり、ほぼ確実にSQL文にあることになります。
 が、そのUPDATE文をCommandBuilderで作っていたのは見落としていました。
# だからソースを載せるのではなく、ソースを日本語にして載せようよ。。。

_________________
katope
会議室デビュー日: 2003/01/24
投稿数: 5
お住まい・勤務地: 名古屋の隣
投稿日時: 2005-05-24 09:14
Jittaさん

そうなのですか。この手の例外はデータベースから返されるリターンにより、出されるものと思っておりました。
思い込みはいけないですね。勉強になります。

VB6時代の話になりますが、本家IBMの技術情報に、IBMのOLEDBは、「バインドコントロールは、読み込みはできるが、
更新には対応していない」というような事が書いてあり、それ以後、AS400のVerがあがるたび、ClientAccessのSPが出るたびに
トライしてきましたが、連結がうまくいかず、これはてっきり、IBMがまだ対応してないからだと勝手に思い込んでおりました。

今回のSP当てにおいて、自分の以前のプログラムも書き換えを行うことなくうまくいき、またたまたま同じような悩みをかかえてらっしゃる
みりゅさんの投稿を発見し、おもわず自分の不勉強も省みず書き込んでしまいました。申し訳ありません。

IBMとMSはUniCodeの解釈の違いで、文字化けしたり、予期せぬ文字長が帰ってきたとか、AccessやSQLServerでは
発生しない例外がいくつか起こってきましたが、Verが上がると改善されてくるので、それも加わって、接続ミドルウェア側と
データベース側の問題と思ってしまったわけです。

話が横道にそれて申し訳ないです。いずれにしても、不勉強を恥じ入るばかりです。

makoto
常連さん
会議室デビュー日: 2004/05/05
投稿数: 40
投稿日時: 2005-08-20 21:18
「Ritmo」というユニークなソフトがありますが。

http://blog.goo.ne.jp/hitsw/e/93dfc88f981a531c04f0d8a99e9b4d28

お役に立てば幸いです。
1

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