60

私はこのコードを試しています:

import sqlite

connection = sqlite.connect('cache.db')
cur = connection.cursor()
cur.execute('''create table item
  (id integer primary key, itemno text unique,
        scancode text, descr text, price real)''')

connection.commit()
cur.close()

私はこの例外をキャッチしています:

Traceback (most recent call last):
  File "cache_storage.py", line 7, in <module>
    scancode text, descr text, price real)''')
  File "/usr/lib/python2.6/dist-packages/sqlite/main.py", line 237, in execute
    self.con._begin()
  File "/usr/lib/python2.6/dist-packages/sqlite/main.py", line 503, in _begin
    self.db.execute("BEGIN")
_sqlite.OperationalError: database is locked

cache.db のパーミッションは問題ありません。何か案は?

4

22 に答える 22

55

あなたのコードはそうではないと言っていますが、実際には sqlite3 を使用していると思います。確認すべき点は次のとおりです。

  1. ファイルにハングしたプロセスがないこと (unix:$ fuser cache.db何も言わないでください)
  2. cache.db のあるディレクトリに cache.db-journal ファイルがありません。これは、適切にクリーンアップされていないクラッシュしたセッションを示しています。
  3. データベース シェルに自身をチェックするように依頼します。$ sqlite3 cache.db "pragma integrity_check;"
  4. データベースのバックアップ$ sqlite3 cache.db ".backup cache.db.bak"
  5. cache.db には何も入っていない可能性があるため (学習しているだけの場合) 削除して、コードを再試行してください。
  6. バックアップが機能するかどうかを確認する$ sqlite3 cache.db.bak ".schema"

それができない場合は、 Things That Can Go WrongHow to Corrupt Your Database Files を読んでください。

于 2010-04-29T21:48:33.653 に答える
52

次のように、接続呼び出しでタイムアウト パラメータを設定します。

connection = sqlite.connect('cache.db', timeout=10)
于 2011-12-23T16:26:09.157 に答える
23

これが古いことは知っていますが、まだ問題が発生しており、これが Google での最初のリンクです。OP は、彼の問題は .db が SMB 共有に置かれていることだと言いました。これはまさに私の状況でした。私の 10 分間の調査は、これが sqlite3 と smb の間の既知の競合であることを示しています。2007 年にさかのぼるバグ レポートを見つけました。

/etc/fstab の smb マウント行に「nobrl」オプションを追加して解決したため、その行は次のようになりました。

//SERVER/share /mnt/point cifs credentials=/path/to/.creds,sec=ntlm,nobrl 0 0

このオプションは、SMB クライアントがバイト範囲ロックをサーバーに送信するのを防ぎます。SMBプロトコルの詳細についてはあまり詳しくありませんが、この設定は、他の誰かがあなたと同じデータベースに書き込もうとしている可能性があるマルチユーザー環境で主に問題になることがわかります. 少なくとも家庭用のセットアップでは、十分安全だと思います。

私の関連バージョン:

  • ミント 17.1 レベッカ
  • SMB v4.1.6-Ubuntu
  • Python v3.4.0
  • SQLite v3.8.2
  • ネットワーク共有は Win12R2 サーバーでホストされています
于 2015-05-17T07:08:04.600 に答える
11

Linux では、たとえば、ロックされたファイルが development.db の場合、同様のことができます。

$ fuser development.db このコマンドは、ファイルをロックしているプロセスを表示します。

development.db: 5430 プロセスを強制終了するだけです...

kill -9 5430 ...データベースのロックが解除されます。

于 2015-07-15T08:36:24.063 に答える
10

dbファイルへのパスが実際にはsambaにマウントされたディレクトリであったために問題が発生したことが判明しました。私はそれを動かしました、そしてそれは働き始めました。

于 2012-09-10T18:51:12.000 に答える
5

同時アクセスの適切な回避策は次のとおりです。

while True:
    connection = sqlite3.connect('user.db', timeout=1)
    cursor = connection.cursor()
    try:
        cursor.execute("SELECT * FROM queue;")
        result = cursor.fetchall()
    except sqlite3.OperationalError:
        print("database locked")
    num_users = len(result)
# ...
于 2010-06-15T14:24:51.590 に答える
5

これは依然としてこの問題に対する Google のトップ ヒットであるため、考えられる原因を追加させてください。データベース構造を編集していて、変更をコミットしていない場合、データベースはコミットまたは元に戻すまでロックされます。

(珍しいかもしれませんが、アプリを開発しているので、コードとデータベースの両方を同時に開発しています)

于 2016-12-09T22:20:24.173 に答える
4

データベースは、書き込み中の別のプロセスによってロックされています。他のトランザクションがコミットされるまで待つ必要があります。connect() のドキュメントを参照してください

于 2010-04-29T21:51:00.363 に答える
3

私が SQLite で遭遇したデータベースがロックされる原因の 1 つとして考えられるのは、あるアプリによって書き込まれ、同時に別のアプリによって読み取られている行にアクセスしようとしたときです。スピンしてデータベースが解放されるのを待つ SQLite ラッパーにビジー タイムアウトを設定することができます (元の C++ API では関数はsqlite3_busy_timeout です)。ほとんどの場合、300ms で十分であることがわかりました。

しかし、あなたの投稿に基づいて、これが問題だとは思いません。最初に他の推奨事項を試してください。

于 2010-04-29T21:52:18.967 に答える
1

ああ、あなたのトレースバックはそれを与えました: バージョンの競合があります。古いバージョンの sqlite をローカルの dist-packages ディレクトリにインストールしましたが、すでに python2.6 ディストリビューションに sqlite3 が含まれていて、古いバージョンの sqlite を必要とせず、おそらく使用できない場合があります。初挑戦:

$ python -c "import sqlite3"

それでもエラーが発生しない場合は、dist-package をアンインストールします

easy_install -mxN sqlite

代わりにimport sqlite3コードで楽しんでください。

于 2010-04-29T22:03:24.320 に答える