質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

566閲覧

C#でのXMLデータファイルの保存で、途中から欠損してしまうことに対しての対策

RC46

総合スコア7

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2023/05/21 02:53

編集2023/05/21 02:55

実現したいこと

XMLデータが稀に途中から欠損してしまうので、そうならないようにしたい

前提

サーバープログラムを組んでいます
メインデータにはXMLで組んでいますが、稀に途中から欠損しておりバグとなっている
おそらく排他処理に問題があるのか、途中で書き込みエラ-となっている

サーバーはソケット通信で処理しており非同期で稼働させています
クライアントは20台程あります

クラインアントからのステータス更新を受け付けたら、xmlを書き換えるという作業をしています
ほぼ同時にクラインアントからの接続がくることもあります

発生している問題・エラーメッセージ

XML

1<Data1> 2 <Data2> 3 <key>165984</key> 4  <SlipStates>063282</SlipStates> 5 <Day>2023/05/24 11:00:00</Day> 6 7 </Data2> 8 <Data2> 9 <key>859521</key> 10  <SlipStates>063850</SlipStates> 11 <Day>2023/05/24 11:00:00</Day> 12 </Data2> 13 <Data2> 14 <key>654485</key> 15  <SlipStates>063850</SlipStates> 16 <Day>2023/05/24 11:00:00</Day> 17 </Data2> 18 <Data2> 19 <key>362114</key> 20 21 22------メモ帳とかで開くと上記の様に途中で切れていることがある 23当然ながら次読み込むときにReadXml でエラ-となる 

該当のソースコード

C#

1コード //おそらく原因と思われるメソッド 2   public bool DateRewriting(string rewriteKey, string rewriteStr) 3 { 4 //時間 5 string strDate = DateTime.Now.ToString(); 6 7 //バックアップ処理(元ファイルをバックアップ用としてコピーして置く) 8 //\\date\main.xmlをリネームして\\date\mainBU.xmlとしてコピーして置く 9 10 using (DataSet set = new DataSet()) 11 { 12 bool flg = false; 13 int waitCount = 1; 14 15 while (!flg) 16 { 17 try 18 { 19 //ファイルロック //排他制御 20 using (FileStream fStream = new FileStream(@"\\date\main.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 21 { 22 // XML の呼び出し 23 set.ReadXml(fStream); 24 25 //データの読み込み 26 using (DataTable table = set.Tables[0]) 27 { 28 //KeyIndex 書き込み対象のKeyのindexを取得 29 var index = table.Rows.IndexOf(table.AsEnumerable().Where(a => a.Field<string>(0) == rewriteKey).FirstOrDefault()); 30 31 //判定 32 if (index != -1) 33 { 34 //ステータス書き換え 35 set.Tables[0].Rows[index][1] = rewriteStr; 36 set.Tables[0].Rows[index][2] = strDate; 37 38 fStream.Seek(0, SeekOrigin.Begin); 39 fStream.SetLength(0); 40 41 //保存 42 set.WriteXml(fStream, XmlWriteMode.WriteSchema); 43 44 } 45 } 46 } 47 flg = true; 48 49 } 50 catch 51 { 52 //10秒は読込を待機させている ファイルロック 53 DelaySleep(500); 54 waitCount++; 55 56 if (waitCount == 20) 57 { 58 //10秒過ぎたらエラーとしている 59 // @"\\date\main.xml" はリネームしてエラー用LOGフォルダに―保存してから削除 60 // "date\mainBU.xml" をリネームして\\date\main.xmlにする 61 return false; 62 } 63 } 64 } 65 return true; 66 } 67 } 68

試したこと

自己学習でC#を実装しております。もしかしたら根本的に排他処理が間違っているのでしょうか?
FileShare.Noneしているので他のクラインアントからアクセスがあっても待機になるはずで2重書き込みみたいなことは起きないと考えています
XMLが途中から欠損してしまうことがあるのか教えて欲しいです
書き込み途中にエラーでWriteXmlまで到達していないということでしょうか?

処理の前にコピーを取ってエラーとなったら戻すやり方に変えてからは運用停止になることはなくなりましたが、バクのログを確認してみると稀に発生しています
ただ、上のコードだとバックアップもクラインアントからの接続の回数だけ行われておりますので負荷的にも大きいかと思います
タイミングによってはバックアップ処理も危ういと思っています

using (FileStream fStream = new FileStream(@"\date\main.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.None))のところが良くないのでしょうか?

あまり的を得ていない質問かもしれませんがよろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/05/21 21:37

> サーバープログラムを組んでいます 「サーバープログラム」とはなんですか? ASP.NET ですか?
episteme

2023/05/22 00:39

> FileShare.Noneしているので他のクラインアントからアクセスがあっても待機になるはずで2重書き込みみたいなことは起きないと考えています ホントに「待機」するんですか? ファイル・オープンに「失敗」するんじゃなくて?
退会済みユーザー

退会済みユーザー

2023/05/22 01:21

XML ファイルに複数のユーザーが同時にアクセスして何かするというところに根本的な問題があるような気がします。気がするだけで確証などはありませんが。SQL Server のような排他制御が組み込まれている DB を利用するのが筋だと思います。
YAmaGNZ

2023/05/22 06:34

>おそらく排他処理に問題があるのか、途中で書き込みエラ-となっている どのようなエラーが発生しているのか確認していないのでしょうか?
RC46

2023/05/22 12:03

ソケット通信を非同期で実行するプログラムを組んでいます サーバーではないかもしれません 各クラインアントからの入力を受け付けてXMLをファイルを書き換えております 500件~1200件/日程処理しております。 すみません待機でなく失敗ししております Try~catchで捕まえてループする形です これも正しいやり方かわかりません SQLServerは触ったことがなく、上記のやり方でサーバーらしきものを立てております 外注するとPC機材の新規購入も含めて数千万~億かかる為、社内でシステムを組んでます SQLは勉強しようかと思います エラーに関してはTry~catchでExceptionを捉えるように組みなおしてログをとるようにしております しかし、そのあとまだエラーが発生していないので判明しておりません 1か月に1回あるかないかというところです 上記メッソドを呼び出すところで lockステートメントはかけております
kikukiku

2023/05/29 02:57 編集

>上記メッソドを呼び出すところで lockステートメントはかけております 該当のxmlファイルへの書き込みに対してのみに、 同時に書き込みが発生しないようにlockをかけているのでしょうか? 念のため、xmlファイルからの読み出しも含めて、 lockをかけるようにしてみてはどうでしょうか?
guest

回答1

0

自己解決

lockステートメントの掛け方を再度見直したところ抜けがありました
滅多に使わないメソッドからのアクセスがあり、二重更新されていました
色々な回答ありがとうございました

投稿2023/06/16 04:15

RC46

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問