0

私はsqliteを使用してチャット履歴を保存していますが、私のアプローチがスレッドセーフであることを懸念しています。

以下の方法は、メッセージをデータベースに追加するために使用するものです。

私のアプローチはスレッドセーフですか?

public class dbHistory {
    public synchronized void addMessage(String from, String agentName, String msg, String time, String channel) {
        try {
            String databaseFileLocation = "jdbc:sqlite:history_" + agentID + ".db";

            Class.forName("org.sqlite.JDBC");
            Connection conn = DriverManager.getConnection(databaseFileLocation);
            PreparedStatement prep = conn.prepareStatement("insert into history values (?, ?, ?, ?, ?);");

            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Calendar cal = Calendar.getInstance();

            prep.setString(1, channel);
            prep.setString(2, from);
            prep.setString(3, msg);
            prep.setString(4, agentName);
            prep.setString(5, dateFormat.format(cal.getTime()));
            prep.addBatch();

            conn.setAutoCommit(false);
            prep.executeBatch();
            conn.setAutoCommit(true);

            conn.close();
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }
}
4

2 に答える 2

1

はい、スレッドセーフですが、遅すぎます。

接続の作成はどの言語でも非常に時間がかかるため、時間を節約するために任意の接続プールを使用する必要があります。また、SimpleDateFormat.format はスレッドセーフではないため、一度に 1 つのスレッドでのみ使用する必要があることに注意してください。

また、「execute」メソッドの周りで autocommit プロパティを管理しないでください。自動コミットは接続のプロパティであり、一度だけ設定する必要があります。falseに設定した場合は、すべての SQL 操作の後に 'commit' メソッドを実行します (または、必要に応じて実行しません)。手動でコミットを管理する必要があります。trueに設定すると、SQL ステートメントが実行されるたびに、接続によってコミット実行が自動的に生成されます。

于 2013-10-18T08:06:54.713 に答える
0

SQLite は 3 つのモードで動作することを覚えておく必要があります。

1.シングルスレッド。このモードでは、すべてのミューテックスが無効になり、一度に複数のスレッドで SQLite を使用するのは安全ではありません。

2.マルチスレッド。このモードでは、1 つのデータベース接続が 2 つ以上のスレッドで同時に使用されない限り、複数のスレッドで SQLite を安全に使用できます。

3.連載。シリアル化モードでは、SQLite を複数のスレッドで制限なく安全に使用できます。

http://www.sqlite.org/threadsafe.html

于 2013-10-18T08:06:58.063 に答える