2013-10-18 133 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