問題タブ [database-locking]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
0 に答える
58 参照

android - Android: データベースを閉じましたがロックされています

タスクを作成して実行するアクティビティがあり、このタスク内でデータベース接続が作成されます。次に、トランザクションを開始し、データベースに対していくつかの操作を行います。向きの変更が表示されたときにタスクがキャンセルされ、変更後に再開されるようにしたい

したがって、onSaveInstanceState メソッドのタスク内でこのメソッドを呼び出します。

しかし、onRestoreInstanceState のタスクでタスクを再起動すると、データベースがロックされていると表示されます。また、データベース接続がトランザクションに入っていないように見えることにも気付きました。

誰でもこの問題を解決する方法を教えてもらえますか?

0 投票する
0 に答える
1231 参照

multithreading - QSQLite エラー: データベースがロックされています

私はQtの開発、スレッド(シグナルとスロット)とデータベース(およびSQLite)の処理方法については初めてです。上記のテクノロジーに取り組み始めてから 4 週間が経ちました。SOに質問を投稿するのはこれが初めてで、皆さんに来る前に調査を行ったと感じています。これは少し長く、おそらく重複しているように見えるかもしれませんが、重複またはtl;drとして却下する前に、一度よく読んでください.

コンテキスト:

データベースで特定の操作 X を実行する Windows アプリケーションに取り組んでいます。アプリケーションは Qt で開発され、データベース エンジンとして QSQLite を使用します。これはシングル スレッド アプリケーションです。つまり、テーブルは順番に処理されます。ただし、DB のサイズ (テーブルとレコードの数) が大きくなるにつれて、この処理は遅くなります。この操作 X の結果は、同じ DB 内の別の結果テーブルに書き込まれます。行われている処理は問題にとって重要ではありませんが、基本的には次のようになります。

Table_X_1 から行を
読み取ります。 Table_X_2 から行を読み取ります。 行に対して
いくつかの操作を行います (読み取りのみ)
結果を Table_X_Results テーブルにプッシュします (これは DB で実行される唯一の書き込みです)。

Table_X_1 と Table_X_2 は、列の数とタイプ、および行の数が同じですが、データのみが異なる場合があります。

私がやろうとしていること:

パフォーマンスを向上させるために、アプリケーションをマルチスレッド化しようとしています。最初に、2 つのスレッドを生成しています (QtConcurrentRun を使用)。2 つのテーブルは、たとえば A と B の 2 つのタイプに分類できます。各スレッドは、2 つのタイプのテーブルを処理します。スレッド内の処理は同じままです。つまり、各スレッド内でテーブルが順次処理されます。

この関数は、SELECT を使用して処理のために行をフェッチし、INSERT を使用して結果を結果テーブルに挿入するようなものです。結果を挿入するために、トランザクションを使用しています。

実際の操作を開始する前に、すべての中間テーブル、結果テーブル、およびインデックスを作成しています。私は毎回接続を開いたり閉じたりしています。スレッドについては、ループに入る前に接続を作成して開きます (スレッドごとに 1 つ)。

問題:

私の処理関数内で、次の(厄介で悪名高い、頑固な)エラーが発生します。

QSqlError(5, "行をフェッチできません", "データベースがロックされています")

(SELECT を使用して) DB から行を読み取ろうとすると、このエラーが発生します。これは、結果テーブルへの INSERT を実行しているのと同じ関数にあります。SELECT と INSERT は同じトランザクション (begin と commit のペア) にあります。INSERT には、準備済みステートメント (SQLiteStatement) を使用しています。

私がやっている一見奇妙なことの理由

  1. 簡単にできるので、QtConcurrentRun を使用してスレッドを作成しています。QThread を使用してみました (QThread をサブクラス化するのではなく、他の方法を使用します)。それも同じ問題につながります。
  2. アプリケーションのクラッシュを避けるために、DSQLITE_THREADSAFE=0 でコンパイルしています。デフォルト (DSQLITE_THREADSAFE=1) を使用すると、アプリケーションが SQLiteStatement::recordSet->Reset() でクラッシュします。また、デフォルトのオプションでは、信頼できない可能性がある内部 SQLITE 同期メカニズムが機能します。必要に応じて、明示的な同期を採用します。
  3. パフォーマンスを向上させるためにアプリケーションをマルチスレッド化し、これを行わない。そこで推奨されているすべての最適化を担当しています。
  4. QSQLITE_BUSY_TIMEOUT=0 で QSqlDatabase::setConnectOptions を使用します。リンクは、DBがすぐにロックされるのを防ぐため、スレッドが「平和的に死ぬ」のに適切な時間を与える可能性があることを示唆しています。これは失敗しました: DB は以前よりも頻繁にロックされました。

観察:

  1. データベースは、スレッドの 1 つが戻るとすぐにロックされます。この動作は一貫しています。
  2. DSQLITE_THREADSAFE=1 でコンパイルすると、スレッドの 1 つが戻ったときにアプリケーションがクラッシュします。呼び出しスタックは、私の関数では SQLiteStatement::recordSet->Reset() を指し、sqlite3.c では winMutexEnter() (EnterCriticalSection() から呼び出される) を指します。これも一貫しています。
  3. QtConcurrentRun を使用して作成されたスレッドは、すぐには終了しません。
  4. QThreads を使用すると、それらを返すことができません。つまり、シグナルとスロットを正しく接続したのに、スレッドが戻らない気がします。スレッドを待つ正しい方法と、スレッドが死ぬまでにかかる時間は?
  5. 実行を終了したスレッドは返されません。DB がロックされているため、エラーが発生します。
  6. SQLITE_BUSY を確認し、スレッドをスリープさせようとしましたが、機能しませんでした。Qtでスリープする正しい方法は何ですか(QtConcurrentRunまたはQThreadsで作成されたスレッドの場合)?
  7. 接続を閉じると、次の警告が表示されます。

    QSqlDatabasePrivate::removeDatabase: 接続 'DB_CONN_CREATE_RESULTS' はまだ使用中です。すべてのクエリが機能しなくなります。

    これは何か意味がありますか?いくつかのリンクは、ローカル QSqlDatabase を使用しているためにこの警告が発生し、接続がクラス メンバーになっている場合は発生しないことを示唆しています。しかし、それが私の問題の原因でしょうか?

さらなる実験:

  1. 結果テーブル (Table_X_Results) のみを含む別のデータベースを作成することを考えています。理論的根拠は、スレッドが 1 つの DB (私が現在持っているもの) から読み取る一方で、別の DB に書き込むことになるということです。しかし、私はまだ同じ問題に直面するかもしれません。さらに、フォーラムとウィキで、2つのスレッドが同じ DB で読み取りと書き込みを行う可能性があることを読みました。では、なぜこのシナリオを機能させることができないのでしょうか?
  2. 現在、SQLITE バージョン 3.6.17 を使用しています。それが問題でしょうか?バージョン 3.8.5 を使用した場合、状況は改善されますか?

すでに調べた Web リソースを投稿しようとしましたが、「2 つ以上のリンクを投稿するには 10 人の担当者が必要です」というメッセージが表示されます。どんな助け/提案も大歓迎です。

0 投票する
2 に答える
9375 参照

database - Delphi: データベースがロックされています (SQLite)

私は2つの問題に直面しています...

(1) Delphi XE6 を使用してデータベース (SQLite) に書き込もうとすると、常にデータベースがロックされているというエラー メッセージが表示されます。コマンド FDConnection1.Close を使用してデータベースにアクセスするたびに、データベースを閉じることは確実です。

(2) 入力パラメータからテーブルに INSERT INTO するにはどうすればよいですか? 次の着信パラメータがあります

次のSQLコマンドでテーブルに書き込もうとしました:

しかし、うまくいかないようです...

以下は、私が問題を抱えている完全な手順です

どんなヒントでも大歓迎です。前もって感謝します。

0 投票する
1 に答える
96 参照

django - テーブルのセクションを書き換えるときにデータベースの一貫性を実現するにはどうすればよいですか?

私は単純なデータベース関係を持っています: 1 つのアイテムは多くの ItemDetails に関連しています。ItemDetails は一度にすべて更新されます。古い ItemDetails を置き換えるための ItemDetails の完全なセットを含むメッセージが HTTP POST 経由で届きます。私が使用するロジックは次のとおりです。

しかし、2 つの送信者が同時に更新を送信すると、競合状態になるようです。(私が思うに) delete() が 2 つのスレッドで多かれ少なかれ並行して実行されてから作成が行われるため、重複したリストが表示されることがあります。

この問題を回避するために、どのロック戦略を使用できますか? 私はPostgreSQLでDjangoを使用しています。

0 投票する
1 に答える
592 参照

java - 他のすべてのクライアントから MongoDB コレクションをロックする方法 (書き込みまたは読み取り)?

(サイドバーにある同様のタイトルの他の質問は、この問題には対応していません。)

履歴シーケンス ジェネレーターのように使用するコレクションがあります。

私はできるようにしたい:

  1. 他のすべてのクライアントからコレクションをロックします (書き込みまたは読み取り)
  2. 最新の seq_id をメモリに読み込む
  3. メモリ内にさらに 3 つのシーケンス ID を生成します (私の場合は Java)。
  4. コレクションに 3 つのドキュメントを挿入する
  5. コレクションのロックを解除

クライアントがステップ 4 に到達する前にステップ 2 と 3 に到達する別のクライアントが競合する seq_ids になるため、クライアントがコレクションをロックしている間、他のすべてのクライアントがコレクションを読み取れないようにロックできるようにしたいと考えています。

0 投票する
1 に答える
796 参照

database - テーブル oracle がロックされました

私はデータベース管理者ではありませんが、テーブルをロックし、結果として大きな混乱を引き起こしているデータベースに問題があります。オラクルのデータベース管理者から情報を入手します。誰かが問題の鍵を見つけるのを手伝ってくれたり、何をする必要があるかを教えてくれたりしたら、ここにさらに情報を入れます:

ここに画像の説明を入力

ここに画像の説明を入力

オラクルから大きなレポートがありますが、データの 95% を理解していません。

0 投票する
1 に答える
99 参照

mysql - 重複に対するデータベース ロック ベースの保護を実現する方法

InnoDB ストレージ エンジンを使用する Web アプリケーションでは、次のシナリオでデータベース ロックを適切に利用できませんでした。

3 つのテーブルがあり、それらを と とaa呼びarますai

aa基本レコード、たとえば記事を保持します。arは、各aaレコードに関連する情報と、 と の関係aaを保持しarます1:m

のレコードは、 からのレコードが最初に読み込まarれたときに保存されます。問題は、2 つの要求が (ほぼ) 同じ時刻に開始されて (関連するレコードが に保存されていない) レコードを読み取ると、レコードが重複することです。aaaaarar

状況を理解するのに役立つ疑似コードを次に示します。

  • aa要求されたレコードを読み取ります。

  • arテーブルをスキャンして、指定されたaaレコードに既に何かが格納されているかどうかを調べます。(そうではないと仮定します。)

  • 特定のレコードaiを何に保存するかを調べるには、相談してください。(やや無関係に思えますが、ロックにも関与する必要があることがわかりました...間違っている可能性があります。)araaai

  • 数行挿入してar

これが私が達成したいことです:

  • aa要求されたレコードを読み取ります。

TRANSACTIONS LOCKarを使用するかどうかに関係なく、読み取りを試行する後続のリクエストは、この時点でar1 つが終了するまで待機します。

  • arテーブルをスキャンして、指定されたaaレコードに既に何かが格納されているかどうかを調べます。(そうではないと仮定します。)問題は、2 つの同時要求の場合、指定されたレコードにレコードが存在しないことを検出し、両方とも同じ行を 2 回挿入することです。araaそれ以外の場合、このシーケンスは中断され、INSERT は発生しません。

  • 特定のレコードaiを何に保存するかを調べるには、相談してください。(やや無関係に思えますが、ロックにも関与する必要があることがわかりました...間違っている可能性があります。)araaai

  • 数行挿入してar

ロックオンを解除するar

単純に思えますが、重複を回避できませんでした。Bash シェル (wget を使用) で単純なコマンドからの同時要求をテストしています。

私は、 http: //dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.htmlhttp://dev.mysql. com/doc/refman/5.5/en/innodb-locking-reads.htmlロックを利用するいくつかの方法を試しましたが、まだ運がありません。

テーブル全体をarロックしたい (INSERT が複数のリクエストから発生するのを防ぎたいため) このテーブルとのやり取りをさらに試行して、最初のロックが解除されるまで待機させます。しかし、ドキュメントには「テーブル全体」がロックされているという言及が 1 つだけありますが (最初のリンク先ページのインテンション ロックのセクション)、それについては詳しく説明されていないか、それを達成する方法を理解できませんでした。

誰かが正しい方向を指すことができますか?

0 投票する
1 に答える
1356 参照

java - SQLite - Java でデータベースがロックされている

最初の方法では、存在しない場合はデータベースを作成します。

2番目の方法では、別の方法で(同じことを行い、更新クエリを変更します)、テーブル内の行が挿入されたかどうかを読み取ろうとします.If table was created now, insert it:

別の呼び出しで、プロジェクトの後で、1 つの行 (ID=1) のみを更新しようとすると、**この行でエラー ** が表示されます:

´

**エラーコード : **

これについて助けが必要です。ありがとう。(私はコミットを使用しません。使用しようとしましたが、エラーも発生します)