并发访问SQLite Da

时间:2014-03-30 07:23:48

标签: java hibernate sqlite concurrency

我正在开发一个包含3个部分的应用: - JavaFX桌面应用程序。 - Java Server WebApp - AndroidApp

我正在使用Hibernate映射SQLite数据库。

但是当桌面应用程序打开并尝试通过服务器从AndroidApp插入新的ibject时,它会给我一个错误:java.sql.SQLException: database is locked

我的hibernate.cfg.xml文件:

<property name="show_sql">true</property>
<property name="format_sql">true</property>
    <property name="dialect">dialect.SQLiteDialect</property>
    <property name="connection.driver_class">org.sqlite.JDBC</property>
    <property name="connection.url">jdbc:sqlite:grainsa_provisional.sqlite</property>
    <property name="connection.username"></property>
    <property name="connection.password"></property>

和我的“对象管理器”,在服务器和桌面中的方式相同:

private Session mSession;
private Transaction mTransaction;

private void initQuery() throws HibernateException {
    mSession = HibernateUtil.getSessionFactory().openSession();
    mTransaction = mSession.beginTransaction();
}

private void manejaExcepcion(HibernateException hibernateException) {
    mTransaction.rollback();
    throw new HibernateException("ha ocurrido un error con la Base de Datos!!!", hibernateException);
}


public Conductor selectConductorByID(Integer id) {
    Conductor conductor = new Conductor();
    try{
        initQuery();
        conductor = (Conductor) mSession.get(Conductor.class, id);
    } catch (HibernateException e){
        manejaExcepcion(e);
        throw e;
    } finally {
        mSession.close();
    }
    return conductor;
}

如果您需要更多信息,请询问!

我做错了什么?

谢谢大家,对不起我的英语!

编辑:我想改变mi桌面JavaFX应用程序的访问模式以通过服务器进行查询,但这需要我很多时间,我不认为这是最好的方法.. < / p>

EDIT2: 这是打开,查询和关闭conatabion到databasa锁定/查询/解锁的正确方法吗?

private void initQuery() throws HibernateException {
    mSession = HibernateUtil.getSessionFactory().openSession();
    mTransaction = mSession.beginTransaction();
}

private void manejaExcepcion(HibernateException hibernateException) {
    mTransaction.rollback();
    throw new HibernateException("ha ocurrido un error con la Base de Datos!!!", hibernateException);
}


public Conductor selectConductorByID(Integer id) {
    Conductor conductor = new Conductor();
    try{
        initQuery();
        conductor = (Conductor) mSession.get(Conductor.class, id);
    } catch (HibernateException e){
        manejaExcepcion(e);
        throw e;
    } finally {
        mSession.close();
    }
    return conductor;
}

请帮忙!再次感谢! 我有点沮丧......

1 个答案:

答案 0 :(得分:0)

来自SQLite FAQ中的FAQ(5):

  

但要小心:此锁定机制可能无法正常工作       如果数据库文件保存在NFS文件系统上。这是因为       fcntl()文件锁定在许多NFS实现上都被破坏了。       如果多个,应该避免将SQLite数据库文件放在NFS上       进程可能会尝试同时访问该文件。       在Windows上,微软的文档称锁定       如果您没有运行Share.exe守护程序,则可能无法在FAT文件系统下运行。       有很多Windows经验的人告诉我这个文件       锁定网络文件是非常错误的,不可靠。       如果他们说的是真的,那么在它们之间共享一个SQLite数据库       两台或多台Windows机器可能会导致意外问题。

也许这就是你问题的原因?你在窗户工作吗?

  

多个进程可以同时打开同一个数据库。       多个进程可以同时执行SELECT。       但只有一个进程可以对数据库进行更改       然而,在任何时候。

SQLLite在多用户场景中存在问题,但如果更新很短且速度很快,则仍然可以正常工作 在您的代码中,您似乎没有正确关闭事务。 也许这种情况下db锁

您应该更改代码以查看hibernate doc here

private Transaction initQuery() throws HibernateException {
    mSession = HibernateUtil.getSessionFactory().openSession();
    mTransaction = mSession.beginTransaction();
    return mTransaction;    
}


public Conductor selectConductorByID(Integer id) {
    Conductor conductor = new Conductor();
    Transaction tx = null;
    try{
        tx = initQuery();
        conductor = (Conductor) mSession.get(Conductor.class, id);
       //flush and commit before close
        mSession.flush();
        tx.commit();
    } catch (HibernateException e){
        manejaExcepcion(e);
        throw e;
    } finally {
        mSession.close();
    }
    return conductor;
}