背景:兩個獨立的進程(非線程)同時對sqlite檔案資料庫進行讀寫操作。sqlite本身支援多進程讀操作,但是並不支援多進程寫操作。所以我需要處理好多進程寫sqlite的問題。
我寫了一個小程式來類比完成這個任務。但是程式裡面沒有添加保護措施。我查了好多的方法,目前自己在用FileLock來互斥進程寫sqilte檔案。
Putter線程代碼:
package com.lockSqlite;import java.io.FileOutputStream;import java.io.IOException;import java.nio.channels.FileLock;/** * 想資料庫放資料 * */public class Putter implements Runnable {private DB db = null;private String name = null;public Putter(String name) {this.name = name;this.db = new DB();}@Overridepublic void run() {for (int i = 0; i < 5000; i++) {boolean result = db.putOne(new Entity("wangxin" + i));if (!result) {System.out.println(name + "放進失敗");} else {System.out.println(name + "放進成功");}}}}
Reader線程讀取資料庫
package com.lockSqlite;import java.util.ArrayList;import org.apache.log4j.Logger;public class Reader implements Runnable {@Overridepublic void run() {ArrayList<Entity> list = new ArrayList<Entity>();DB db = new DB();for (int i = 0; i < 5000; i++) {list = db.getAll();System.out.println("讀取到:--->");for (int j = 0; j < list.size(); j++) {}System.out.println("讀取結束:--->");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}
資料庫的操作類:
db.java
package com.lockSqlite;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;public class DB {private static Connection connection = null;private static PreparedStatement preparedStatement = null;private ResultSet resultset = null;public static boolean init() {try {Class.forName(Constants.JDBC_URL);connection = DriverManager.getConnection(Constants.CONNECTION_URL+ Constants.DB_NAME);} catch (ClassNotFoundException e) {System.out.println("類找不到");return false;} catch (SQLException e) {System.out.println("SQL異常");return false;}String sql = "CREATE TABLE IF NOT EXISTS '" + Constants.HIEP_TB+ "'(name TEXT,age TEXT);";ResultSet resultset = null;try {preparedStatement = connection.prepareStatement(sql);preparedStatement.execute();return true;} catch (SQLException e1) {e1.printStackTrace();return false;}}private boolean isExist(String name) {String sql = "select * from '" + Constants.HIEP_TB + "' where name=?";try {preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, name);resultset = preparedStatement.executeQuery();if (resultset.next()) {return true;}} catch (SQLException e) {e.printStackTrace();return false;}return false;}public synchronized boolean putOne(Entity one) {if (isExist(one.getName())) {System.out.println("已經存在");return false;} else {String sql = "INSERT INTO '" + Constants.HIEP_TB + "' VALUES (?,?)";try {preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, one.getName());preparedStatement.setString(2, one.getAge());preparedStatement.executeUpdate();return true;} catch (SQLException e) {e.printStackTrace();}}return false;}public ArrayList<Entity> getAll() {ArrayList<Entity> list = new ArrayList<Entity>();Entity one = new Entity();String sql = "select * from hiepTB";try {preparedStatement = connection.prepareStatement(sql);resultset = preparedStatement.executeQuery();while (resultset.next()) {one.setName(resultset.getString("name"));one.setAge(resultset.getString("age"));list.add(one);}return list;} catch (SQLException e) {e.printStackTrace();return null;}}}
存到資料庫的實體類:Entity.java
package com.lockSqlite;public class Entity {private String name;private String age;public Entity() {}public Entity(String name) {this.age = 0 + "";this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Entity [name=" + name + ", age=" + age + "]";}}
兩個進程測試類別:
public class TestMain1 {public static void main(String[] args) throws Exception {DB.init();new Thread(new Putter("putter1")).start();new Thread(new Putter("putter2")).start();new Thread(new Putter("putter3")).start();new Thread(new Putter("putter4")).start();new Thread(new Putter("putter5")).start();new Thread(new Putter("putter6")).start();new Thread(new Putter("putter7")).start();new Thread(new Putter("putter8")).start();new Thread(new Reader()).start();}}
另一個測試進程:
package com.lockSqlite;public class TestMain2 {public static void main(String args[]) {DB.init();new Thread(new Putter("putter1")).start();new Thread(new Putter("putter2")).start();new Thread(new Putter("putter3")).start();new Thread(new Putter("putter4")).start();new Thread(new Putter("putter5")).start();new Thread(new Putter("putter6")).start();new Thread(new Putter("putter7")).start();new Thread(new Putter("putter8")).start();new Thread(new Reader()).start();}}
我想用FileLock來處理,但是一直沒成功。希望大家幫幫我啊。
原工程代碼: