🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

1回答

2384閲覧

Postgresqlのレコードのロックが外れる

wakaranchin

総合スコア15

C#

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

1クリップ

投稿2020/11/27 08:45

編集2020/11/27 08:46

前提・実現したいこと

C#を使用してDBの更新を行おうと思っているのですが、その際排他制御をしたく、レコードにロックをかけようと思ったのですがロックが外れてしまいます。

該当のソースコード

C#

1public Shaindata_select(string storage) 2{ 3 //接続文字列 4 string conn_str = "Server=***;Port=5432;User ID=postgres;Database=System;Password=***;Enlist=true"; 5 6 using (NpgsqlConnection conn = new NpgsqlConnection(conn_str)) 7 { 8 //PostgreSQLへ接続 9 conn.Open(); 10 11 string sql = @"BEGIN transaction; select id,name,gakureki,birthday,sex,nyushabi from syain WHERE id =" + storage + "FOR UPDATE;"; 12 13 NpgsqlCommand cmd = new NpgsqlCommand(sql, conn); 14 //クエリ実行 15 using (NpgsqlDataReader dr = cmd.ExecuteReader()) 16 { 17 //レコードなしの場合 18 if (dr.HasRows == false) { } 19 while (dr.Read()) { } 20 } 21///ここまではロックがかかっている/// 22 conn.Close(); 23///DBを閉じるとロックが解ける??/// 24 } 25}

試したこと

DBを閉じる前に検証するとロックがかかった状態になっているので、DBを閉じてしまうことによってロックが解除されてしまっているのでしょうか?初心者でわからないことばかりですみません。

補足情報(FW/ツールのバージョンなど)

Visual Studio2019

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/11/27 09:41

XY 問題になっていると思いますよ。Y だけでなく、X も書くことをお勧めします。
guest

回答1

0

ベストアンサー

「DBを閉じてしまうことによってロックが解除されてしまっている」です。

接続の切れた、データベースに対しては、なんの制御も効きません。

投稿2020/11/27 09:05

showkit

総合スコア1638

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

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

wakaranchin

2020/11/27 09:08

プログラムが終了しても接続を保ち続ける方法などはあるのでしょうか…?
showkit

2020/11/27 09:49

ありません。質問者さんがやりたいことの別解として、排他するためのフラグを持つ、特別なテーブルを作成して、ある特定のプログラムだけに、そのフラグをオン/オフする権限と持たせます。 他のプログラムは、そのテーブルを参照して、フラグが解除されるまでは、他のテーブルにアクセスさせないようなプログラミングをするというやり方があります。
wakaranchin

2020/11/30 00:00

なるほど…なんだかまどろっこしい感じもしますがそのような方法しかないんですね…
wakaranchin

2020/11/30 00:04

ベストアンサーに選んだ後にすみません。上記の方法ですと、FOR UPDATEやCOMMITなどは使わずに排他するテーブルを参照するということだけで排他制御するということですよね…?
showkit

2020/11/30 02:26

はい。そういうことになります。ただし、排他フラグを持つテーブルに対してアクセスする際はもちろん、他のテーブルにアクセスする際もトランザクションをかけて、コミットまたは ロールバックするようにしないと思わぬ落とし穴に落ちることもありますので、トランザクションは、しっかりかけるようにしましょう。
wakaranchin

2020/11/30 05:35

分かりました。ありがとうございます。
wakaranchin

2020/12/01 08:54

何度もすみません。DBの内容変更をクライアントで行っている間もプログラムを終了せずに、ボタン押下時にプログラムをまた走らせるという方法もあるのでしょうか…?自分で試そうと思ったのですが、現在ボタン押下時にメソッドを起動するというやり方しかわからず、ボタン押下されたか取得するコードの書き方が分かりません…
showkit

2020/12/01 09:19

ん~と。ちょっと質問の内容が理解しにくいです。ちなみに クライアントがさわる プログラムは 単体のアプリケーションですか? それとも ブラウザで WEB 画面を開くイメージですか?
wakaranchin

2020/12/02 00:02

単体のアプリケーションです。データの更新削除を行うときのみサーバーのDBにSQLを発行する形です。
wakaranchin

2020/12/02 00:11

SELECT(データの取得)→クライアントでデータの変更→クライアントでボタン押下時UPDATE という流れを1画面でやるのですが、この流れで最初のSELECT時にロックをかけて最後のUPDATE時に解除する方法はないんでしょうか・・・
showkit

2020/12/07 03:19

やり方として、最初のSELECT時に トランザクション開始。UPDATE 押下で UPDATE 完了時点で コミット。UPDATE なしで離れる場合は、ロールバック。UPDATE なしで 終了しても前の状態は 保たれいるので 問題ないのでは?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問