2013-10-18 88 views
0

我使用sqlite存储聊天记录我现在担心天气我的方法是线程安全的。Java线程安全的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); 
     } 
    } 
} 

回答

1

是的,它是线程安全的,但速度太慢。

创建连接对于任何语言来说都是非常慢的操作,所以您应该使用任何连接池来节省时间。 另外你应该记住SimpleDateFormat.format不是线程安全的,所以你应该一次只在一个线程中使用它。

此外,您不应该管理'execute'方法的autocommit属性。自动提交是连接的属性,您应该只设置一次。 如果您将其设置为false,则在每次sql操作(如果需要)之后执行'commit'方法 - 您应该手动管理提交。 如果你把它设置为,您的连接会产生每一个SQL语句的执行

+0

我怎么能建立一个连接,我可以重用? – Alosyius

+0

@Alosyius,例如,您可以使用连接池。你可以手动编写它们,或者你可以使用已知的花费像c3p0 http://sourceforge.net/projects/c3p0/ – omickron

0

你应该记住,SQLite的可在3种模式下工作后,自动提交执行:

1.单线程。在这种模式下,所有的互斥锁都被禁用,并且SQLite不安全,可以同时在多个线程中使用。

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

3.串行化。在序列化模式下,SQLite可以安全地由多个线程使用,没有任何限制。

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