0

org.xerial:sqlite-jdbc 3.28.0 と共に mybatis 3.4.6 を使用しています。以下は、共有モードを有効にしてメモリ内データベースを使用するための私の構成です

db.driver=org.sqlite.JDBC
db.url=jdbc:sqlite:file::memory:?cache=shared

このテストクラスdb.urlによると、は正しいです

また、mybatis 構成の下で正しいトランザクション分離レベルをセットアップすることができましたが、私からも報告されているこの問題によるとプロパティ read_uncommitted のタイプミスがあります。

<environment id="${db.env}">
    <transactionManager type="jdbc"/>
    <dataSource type="POOLED">
        <property name="driver" value="${db.driver}" />
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
        <property name="defaultTransactionIsolationLevel" value="1" />
        <property name="driver.synchronous" value="OFF" />
        <property name="driver.transaction_mode" value="IMMEDIATE"/>
        <property name="driver.foreign_keys" value="ON"/>
    </dataSource>
</environment>

この設定行

  <property name="defaultTransactionIsolationLevel" value="1" />

PRAGMA read_uncommittedの正しい値を設定するトリックを行います

接続を初期化し、値が正しく設定されていることを確認する下のコードをデバッグしたので、私はそれを確信しています

ただし、上記の設定では、私のプログラムは読み取り中に断続的に SQLITE_LOCKED_SHAREDCACHE に遭遇します。これは、下のスクリーンショットの赤い四角形で強調表示されている説明によると、発生すべきではないと思います。このエラーの発生確率は低いですが、原因と解決方法を知りたいです。

どんなアイデアでも大歓迎です!!

デバッグ構成は以下のとおりです


===CONFINGURATION==============================================
 jdbcDriver                     org.sqlite.JDBC
 jdbcUrl                        jdbc:sqlite:file::memory:?cache=shared
 jdbcUsername                   
 jdbcPassword                   ************
 poolMaxActiveConnections       10
 poolMaxIdleConnections         5
 poolMaxCheckoutTime            20000
 poolTimeToWait                 20000
 poolPingEnabled                false
 poolPingQuery                  NO PING QUERY SET
 poolPingConnectionsNotUsedFor  0
 ---STATUS-----------------------------------------------------
 activeConnections              5
 idleConnections                5
 requestCount                   27
 averageRequestTime             7941
 averageCheckoutTime            4437
 claimedOverdue                 0
 averageOverdueCheckoutTime     0
 hadToWait                      0
 averageWaitTime                0
 badConnectionCount             0
===============================================================

ここに画像の説明を入力

添付ファイル:

例外は以下です

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: org.sqlite.SQLiteException: [SQLITE_LOCKED_SHAREDCACHE]  Contention with a different database connection that shares the cache (database table is locked)
### The error may exist in mapper/MsgRecordDO-sqlmap-mappering.xml
### The error may involve com.super.mock.platform.agent.dal.daointerface.MsgRecordDAO.getRecord
### The error occurred while executing a query
### Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: org.sqlite.SQLiteException: [SQLITE_LOCKED_SHAREDCACHE]  Contention with a different database connection that shares the cache (database table is locked)
4

1 に答える 1

0

私は最終的にこの問題を自分で解決し、他の誰かが将来同様の問題に遭遇した場合に備えて、以下の回避策を共有します.

まず、以下に示す例外の完全なコール スタックを取得できます。 ここに画像の説明を入力

コールバックによって示されるソース コードを調べると、以下の結果が得られます。

  1. SQLite はデフォルトで自動コミットを有効にして組み込まれています。これは、SqlSessionManager を使用しているため、デフォルトで自動コミットを無効にする MyBatis と矛盾します。
  2. setDesiredAutoCommitMyBatis は、最終的に呼び出すメソッドを使用して、接続の初期化中に自動コミット プロパティをオーバーライドします。SQLiteConnection#setAutoCommit
  3. SQLiteConnection#setAutoCommitトランザクション モードを IMMEDIATE に設定しているため、詳細な説明については、以下のソース コードのスクリーンショットを参照してください

<property name="driver.transaction_mode" value="IMMEDIATE"/>

ここに画像の説明を入力 ここに画像の説明を入力

したがって、これまでの明らかな解決策は、トランザクション モードをDEFERREDに変更することです。なお、自動コミット設定をMyBatisとSQLiteで同じにする解決策も検討されましたが、初期化段階でSQLiteConnectionの自動コミットを設定する方法がなく、常に切り替え(からtrue から false へ、またはその逆)、おそらくトランザクション モードが適切に設定されていない場合、切り替えによって上記のエラーが発生します。

于 2020-10-21T10:06:44.087 に答える