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 不是线程安全的,因此您一次只能在一个线程中使用它。

此外,您不应围绕“执行”方法管理自动提交属性。自动提交是一个连接的属性,你应该只设置一次。如果将其设置为false,则在每次 sql 操作后执行 'commit' 方法(或者不执行,如果需要) - 您应该手动管理提交。如果将其设置为true,您的连接将在每个 sql 语句执行后自动生成提交执行

于 2013-10-18T08:06:54.713 回答
0

您应该记住 SQLite 可以在 3 种模式下工作:

1.单线程。在这种模式下,所有互斥锁都被禁用,SQLite 一次在多个线程中使用是不安全的。

2.多线程。在这种模式下,SQLite 可以被多个线程安全地使用,前提是没有在两个或多个线程中同时使用单个数据库连接。

3.序列化。在序列化模式下,SQLite 可以不受限制地被多个线程安全使用。

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

于 2013-10-18T08:06:58.063 回答