<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<META NAME="GENERATOR" CONTENT="GtkHTML/3.3.2">
</HEAD>
<BODY>
Dear Ignas,<BR>
<BR>
Thanks for this excellent and informative problem report. Since I do run sqlite3 and <BR>
SBCL here at home, I should be able to use your test code to reproduce the problem.<BR>
I will try to do this tonight and tomorrow morning; I doubt I willl have much information<BR>
for your before tomorrow at noon.<BR>
<BR>
Looking at the stack trace you provide, it seems that this is a SQLite error, possibly<BR>
cause by Elephant, or even CLSQL, not handling transactions properly. Since I have <BR>
only minimal knowledge of SQLite, I can't say anything else yet.<BR>
<BR>
Tonight I will run your test code against a postgres database as well; this may not<BR>
solve your problem but will give us some additional information.<BR>
<BR>
I am a little surprised by your use of clsql:start-transaction; the normal idiom for<BR>
this is:<BR>
<BR>
(with-transaction (:store-controller *store-controller*)<BR>
(loop for obj in objs<BR>
for key in keys<BR>
do (setf (get-value key bt) obj))))<BR>
(this is an example for testcollections.lisp)<BR>
<BR>
Are you saying in your email that you could not use this way of doing things? The <BR>
with-transaction macro should be indpendent of the type of the store-controller.<BR>
<BR>
You wrote:<BR>
<TT>As sqlite requires each thread to have it's own connection by throwing</TT><BR>
<TT>an error if one thread tries to reuse a connection created by another</TT><BR>
<TT>thread at least on Ubuntu Dapper. Google says that it depends on a</TT><BR>
<TT>compile time flag for libsqlite3.</TT><BR>
<BR>
The current Elephant code has no notion of this, and I'm pretty sure it will hand the same connection<BR>
to several threads. Obviously, you could solve this problem by using mutexes to make sure that<BR>
only one thread accesses the controller, but that might be quite unpleasant for you code.<BR>
<BR>
If these comments can help you provide anymore information about what your possible solutions<BR>
are, please reply so I can think about it before I begin debugging it tonight or tomorrow.<BR>
<BR>
On Wed, 2006-04-19 at 18:34 +0300, Ignas Mikalajunas wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
<FONT COLOR="#000000"> Hi, I am trying to use elephant as a backend data store for my</FONT>
<FONT COLOR="#000000">blogging application. And have encountered some problems with it ...</FONT>
<FONT COLOR="#000000">As i want to only commit the transaction in cases of error and tbnl is</FONT>
<FONT COLOR="#000000">using throw for redirects i need to manualy open/close transactions,</FONT>
<FONT COLOR="#000000">but it seems (ele:start-transaction) is only designed to work with BDB</FONT>
<FONT COLOR="#000000">backend, so i must use (clsql:start-transaction) instead.</FONT>
<FONT COLOR="#000000">At the moment the wrapper around each request looks like this:</FONT>
<FONT COLOR="#000000">(defun common-blog-view-wrapper (function)</FONT>
<FONT COLOR="#000000"> (ele:with-open-store (`(:sqlite3 ,(format nil "~A"</FONT>
<FONT COLOR="#000000">(get-config-option "database-path"))))</FONT>
<FONT COLOR="#000000"> (let ((error nil)</FONT>
<FONT COLOR="#000000"> (transaction nil))</FONT>
<FONT COLOR="#000000"> (unwind-protect</FONT>
<FONT COLOR="#000000"> (handler-bind ((error (lambda (cond)</FONT>
<FONT COLOR="#000000"> (declare (ignore cond))</FONT>
<FONT COLOR="#000000"> (setf error t))))</FONT>
<FONT COLOR="#000000"> (clsql:start-transaction)</FONT>
<FONT COLOR="#000000"> (setf transaction t)</FONT>
<FONT COLOR="#000000"> (tbnl::string-to-octets (funcall function) :utf-8))</FONT>
<FONT COLOR="#000000"> (when transaction</FONT>
<FONT COLOR="#000000"> (if error</FONT>
<FONT COLOR="#000000"> (clsql:rollback)</FONT>
<FONT COLOR="#000000"> (clsql:commit)))))))</FONT>
<FONT COLOR="#000000">As sqlite requires each thread to have it's own connection by throwing</FONT>
<FONT COLOR="#000000">an error if one thread tries to reuse a connection created by another</FONT>
<FONT COLOR="#000000">thread at least on Ubuntu Dapper. Google says that it depends on a</FONT>
<FONT COLOR="#000000">compile time flag for libsqlite3. Everything works more or less fine ,</FONT>
<FONT COLOR="#000000">but when i am reloading the page multiple times in a row very fast i</FONT>
<FONT COLOR="#000000">am getting a traceback (attached). And can't quite grok what went</FONT>
<FONT COLOR="#000000">wrong ... Maybe some one who knows internals of elephant can help me</FONT>
<FONT COLOR="#000000">out with this, as i could not really track where could a database</FONT>
<FONT COLOR="#000000">connection appear in another thread.</FONT>
<FONT COLOR="#000000">A testcase for SBCL:</FONT>
<FONT COLOR="#000000">(defun test ()</FONT>
<FONT COLOR="#000000"> (ele:with-open-store ('(:sqlite3 "/home/ignas/src/common-blog/dev.db"))))</FONT>
<FONT COLOR="#000000">(sb-thread:make-thread #'test) ;; a few times - works</FONT>
<FONT COLOR="#000000">(dotimes (i 3) (sb-thread:make-thread #'test)) ;; you get 3 tracebacks</FONT>
<FONT COLOR="#000000">By the way thanks for a wonderful library!</FONT>
<FONT COLOR="#000000">--</FONT>
<FONT COLOR="#000000">Ignas Mikalajūnas</FONT>
<FONT COLOR="#000000">_______________________________________________</FONT>
<FONT COLOR="#000000">elephant-devel site list</FONT>
<FONT COLOR="#000000"><A HREF="mailto:elephant-devel@common-lisp.net">elephant-devel@common-lisp.net</A></FONT>
<FONT COLOR="#000000"><A HREF="http://common-lisp.net/mailman/listinfo/elephant-devel">http://common-lisp.net/mailman/listinfo/elephant-devel</A></FONT>
</PRE>
</BLOCKQUOTE>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
----<BR>
Robert L. Read, PhD read &T robertlread.net<BR>
Consider visiting Progressive Engineering: http://robertlread.net/pe<BR>
In Austin: 912-8593 "Think globally, Act locally." -- RBF<BR>
<BR>
<BR>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>