dimanche 18 mai 2014

Java - accès simultané SQLite Da - Stack Overflow


I´m developing an app with 3 parts: - JavaFX Desktop app. - Java Server WebApp - AndroidApp


I´m using Hibernate for mapping a SQLite Database.


But when the desktop app is open and try to insert a new ibject from the AndroidApp throug the Server it gives me an error: java.sql.SQLException: database is locked


My hibernate.cfg.xml file:


<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>

And my "Objects Manager",the same way in the Server and in the Desktop by example:


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;
}

If you need more information please ask!


What i´m doing wrong?


Thanks everyone and sorry about my english!


Edit: ím thinking to change the acces mode of mi desktop JavaFX app to make the query through the server, but it will take me alot of time, and i do not think that is the best way to do it..


Edit2: This is the right way to open, make query and close the conexion to the databasa to lock/query/unlock?


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;
}

Please help! and thanks again! I´m a little bit deseperated...




From FAQ (5) in SQLite FAQ:



But use caution: this locking mechanism might not work correctly if the database file is kept on an NFS filesystem. This is because fcntl() file locking is broken on many NFS implementations. You should avoid putting SQLite database files on NFS if multiple processes might try to access the file at the same time. On Windows, Microsoft's documentation says that locking may not work under FAT filesystems if you are not running the Share.exe daemon. People who have a lot of experience with Windows tell me that file locking of network files is very buggy and is not dependable. If what they say is true, sharing an SQLite database between two or more Windows machines might cause unexpected problems.



Maybe this is the cause for you problem? Are you working on windows?



Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.



SQLLite is problematic in multi-user scenarios, but can still work fine if updates are short and fast.
In your code it looks like you are not closing the transaction correctly. Maybe this case the db lock


You should change the code to see 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;
}


I´m developing an app with 3 parts: - JavaFX Desktop app. - Java Server WebApp - AndroidApp


I´m using Hibernate for mapping a SQLite Database.


But when the desktop app is open and try to insert a new ibject from the AndroidApp throug the Server it gives me an error: java.sql.SQLException: database is locked


My hibernate.cfg.xml file:


<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>

And my "Objects Manager",the same way in the Server and in the Desktop by example:


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;
}

If you need more information please ask!


What i´m doing wrong?


Thanks everyone and sorry about my english!


Edit: ím thinking to change the acces mode of mi desktop JavaFX app to make the query through the server, but it will take me alot of time, and i do not think that is the best way to do it..


Edit2: This is the right way to open, make query and close the conexion to the databasa to lock/query/unlock?


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;
}

Please help! and thanks again! I´m a little bit deseperated...



From FAQ (5) in SQLite FAQ:



But use caution: this locking mechanism might not work correctly if the database file is kept on an NFS filesystem. This is because fcntl() file locking is broken on many NFS implementations. You should avoid putting SQLite database files on NFS if multiple processes might try to access the file at the same time. On Windows, Microsoft's documentation says that locking may not work under FAT filesystems if you are not running the Share.exe daemon. People who have a lot of experience with Windows tell me that file locking of network files is very buggy and is not dependable. If what they say is true, sharing an SQLite database between two or more Windows machines might cause unexpected problems.



Maybe this is the cause for you problem? Are you working on windows?



Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.



SQLLite is problematic in multi-user scenarios, but can still work fine if updates are short and fast.
In your code it looks like you are not closing the transaction correctly. Maybe this case the db lock


You should change the code to see 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;
}

0 commentaires:

Enregistrer un commentaire