日付時間型データの保存で同時実行違反エラー

解決


デンデン  2005-03-24 01:20:59  No: 120399

(環境) WinXP,VB.Net
でAccess2000形式のMDBへ日付時間型データの保存を行おうとしたところ「同時実行違反エラー」が発生して保存できませんでした。

コーディング:
        TEST_DA.Fill(TesT_DS1)

        '[EditDate]は日付/時刻型
        TesT_DS1.Tables(0).Rows(0)("EditDate") = Now.ToString
        TEST_DA.Update(TesT_DS1)

        ※あらかじめデータアダプタ(TEST_DA)とデータセット(TesT_DS1)は生成してあります。

該当レコードの日付データはMDBを直接手入力して「2004/03/01 12:00:00」をセットしておきました。

どこに原因があるのか教えてもらえないでしょうか。なお、データに時間を設定しない場合はエラーにはなりませんでした。


。。。  2005-03-24 02:35:51  No: 120400

デバッグ依頼はお断り


デンデン  2005-03-24 03:49:12  No: 120401

デバッグ依頼ではなかったのですが確かに文章を読むとそう見えますね。すみません。

実際にやりたいことは単純にMDBに日付(時間有り)を保存したいのですが、Now.ToStringをセットしてもMDBには時間データが保存されないようなのです(セットしていた[2004/03/01 12:00:00]は消去しました)がどうすれば時間データ付でデータを保存できるようになるのでしょうか。


特攻隊長まるるう  2005-03-24 04:15:23  No: 120402

本来、同時実行違反エラーは2人のユーザが同時に編集した時に起こるはずだけど…
[同時実行例外の処理]
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/Vbcon/html/vbwlkhandlingconcurrencyexception.asp
心当たりはありますか?。

余談ですが、Now.ToString は色々とマズい動きをします…。
システムの日付の書式設定に依存するので、和暦で区切り文字
を"-"とかに設定すると"17-03-23 17:58:18"という文字列に
なった思い出が…。
テーブルは日付型なんでしょ?なぜ文字列型に変換してるのでしょ?
   TesT_DS1.Tables(0).Columns("EditDate").DataType.Name
が "DateTime" であることだけ確かめて
   TesT_DS1.Tables(0).Rows(0)("EditDate") = Now
でいいんじゃないかなぁ…。
今後、文字列にする場合でも確かめた方が良いと思われます。
日付型に変換して扱っている場合は問題は出てこないかもしれません
が、SQL文などの編集に組み込むと不具合を起こします。

あと、データアダプタは UpdateCommand を設定して無いと
更新できなかった気もしますが…。データが更新されてなければ
参考にして下さい。
[ADO.NET基礎講座 第6回  データセットを使ったレコードの更新と削除]
http://www.atmarkit.co.jp/fdotnet/basics/adonet06/adonet06_02.html


なるなる  2005-03-24 04:18:38  No: 120403

回答レスではなく横から申し訳ありません。

私も以前に同じ事で悩んだことがありました。当時はまだ初心者で(今もですが)
その時は時間データは不要だったこともあり、不思議だと思いながらも棚上げして
ました。とゆうことでこのスレッドに興味があり思わず書込みしてしまいました。
後学のため私も以降の回答レスに期待です。


デンデン  2005-03-24 04:32:14  No: 120404

特攻隊長まるるうさん、レスありがとうございます。

同時実行違反ですが、スタンドアロンで更新を一度行っただけでエラーになりました。

また、[Now]でテストしてみましたがやはり時間データは登録されませんでした([2005/03/23 0:00:00]になっています)。型は"DateTime"になっていました。


魔界の仮面弁士  2005-03-24 04:33:36  No: 120405

> TesT_DS1.Tables(0).Rows(0)("EditDate") = Now.ToString
ToString()する必要があるかどうかは兎も角として……

とりあえず現状では、OleDbDataAdapter の UpdateCommand の内容に
問題があるのだろう、としか答えられません。


デンデン  2005-03-24 07:41:14  No: 120406

魔界の仮面弁士さん、レスありがとうございます。

私は初心者なのでデータアダプタの構成はウィザードを使用して生成しています。以下はUpdateCommandの内容です。

CommandText:
UPDATE TestTable SET [Index] = ?, EditDate = ? WHERE ([Index] = ?) AND (EditDate = ? OR ? IS NULL AND EditDate IS NULL)

※[Index]はPrimaryKeyです。またその他の項目は削除しています。

もしかして、ウィザードで自動生成するとうまくいかないのでしょうか。


魔界の仮面弁士  2005-03-24 08:52:18  No: 120407

まずは、問題の切り分けから行いましょうか。

WHERE句以下には、同時実行制御の為の、複雑な条件式が書かれていますね。
http://www.microsoft.com/japan/msdn/library/ja/cpguide/html/cpconoptimisticconcurrency.asp
http://www.atmarkit.co.jp/fdotnet/basics/adonet07/adonet07_04.html

まずはここを簡潔にしてみて、それでもエラーになるかどうかを調べてみましょう。
UpdateCommand の CommandText を以下のように変更してから、
正常動作するかどうかを確認してみてください。
(列の同時更新判定を省き、主キーのみでの検索にしてあります)

  UPDATE TestTable SET EditDate = ? WHERE [Index] = ?

> データに時間を設定しない場合はエラーにはなりませんでした
あー……もしかして。
時間が無い(00:00:00)場合にうまくという事は、
  .UpdateCommand.Parameters( 日付パラメータ列 ).OleDbType
の内容が、OleDb.OleDbType.Date ではなく OleDb.OleDbType.DBDate に
なっていませんか?

Date は「日付と時刻」を持つ型ですが、DBDate は「日付部のみ」を
扱う型ですので、時刻部が切り捨てて比較されてしまい、
UpdateCommandが「更新件数 ゼロ → 同時実行違反」と判断しているのかも。

# あくまで予想なので、間違っているかもしれませんけど。


デンデン  2005-03-24 21:29:35  No: 120408

レスが遅れてすみませんでした。

>.UpdateCommand.Parameters( 日付パラメータ列 ).OleDbType
>の内容が、OleDb.OleDbType.Date ではなく OleDb.OleDbType.DBDate に
>なっていませんか?

まさにそのとおりでした。この部分を変更したら時間有りの登録ができるようになりました。また、同時実行違反エラーも出なくなりました。今回もまた一つ勉強になりました。

どうもありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加