Обсуждение: [Fwd: [Fwd: Re: solved: fastpath error?]]

Поиск
Список
Период
Сортировка

[Fwd: [Fwd: Re: solved: fastpath error?]]

От
Barry Lind
Дата:
   Micheal,

Are you still having problems here?  If so could you explain what
problems you still have?  It wasn't clear when I reread this message
what you had solved and what was still a problem.

thanks,
--Barry

-------- Original Message --------

Subject: Re: [JDBC] solved: fastpath error?
Date: Wed, 05 Jun 2002 19:01:18 +0200
From: "M. Dietrich"
Reply-To: mdt@emdete.de
Organization: emdete
To: Barry Lind
References: <20020506134350.GE3762@emdete.de> <3CD6AD9D.7000402@xythos.com>

On Mon, May 06, 2002 at 09:21:49AM -0700, Barry Lind wrote:
  > >i get still those fastpath errors with the jdbc drivers. i tested the
  > >driver installed with debian, the stable and the development driver
  > >from jdbc.postgresql.org. has anybody else the same problem?
  > >
  > >i use blobs alot. using blobs with pg-sql's jdbc does not work
  > >strait-forward in a jdbc-manner like this:
  > >
  > >    statement.setBinaryStream(4, in, size);
  > >
  > >even this does not work:
  > >
  > >    byte buffer[] = new byte[(int)size];
  > >        in.read(buffer);
  > >        statement.setBytes(4, buffer);
  > >
  > >
  > >so this one is what i found out works best for me:
  > >
  > >    org.postgresql.largeobject.LargeObjectManager lom =
  > >    ((org.postgresql.Connection)getConnection()).getLargeObjectAPI();
  > >    int loid = lom.create();
  > >    org.postgresql.largeobject.LargeObject blob = lom.open(loid);
  > >    int s;
  > >    byte buf[] = new byte[2048];
  > >        while ((s = in.read(buf, 0, buf.length)) > 0)
  > >            blob.write(buf, 0, s);
  > >        blob.close();
  > >    java.sql.Blob b = new
  > >
org.postgresql.largeobject.PGblob((org.postgresql.Connection)getConnection(),

loid);
  > >        statement.setBlob(4, b);
  > >
  > >but using this i get the fast-path error. using the other versions
  > >results in a errormessage containing all the binary data.
  > What version of postgres and what version of the jdbc drivers are you
  > using?
  >
  > Also, more info would be helpful.  When you say 'doesn't work' that
  > doesn't give us a lot to go on.  Error messages and any output you
  > are getting would help a lot.

i use the stable version 7.2 and the development version i downloaded
from the server:

-rw-r--r--    1 mdt      mdt         96179 16. Apr 23:55 devpgjdbc2.jar


in my application png-images will be filled into a database. this is
the create-statement i use for the table:

CREATE TABLE MD_DOCUMENT ( MD_DESCRIPTION CHARACTER VARYING(300),
MD_ENTRYDATE TIMESTAMP DEFAULT NOW(),  MD_MIMETYPE CHARACTER
VARYING(300),  MD_DATA OID,  MD_OID BIGINT NOT NULL)
CREATE UNIQUE INDEX MD_IDOCUMENT ON MD_DOCUMENT(MD_OID)


using the first methode, i get the error (jdbc-log enabled, btw why
doesn't the log provide the version?):


DriverManager.getConnection("jdbc:postgresql://localhost:5432/sally")
      trying
driver[className=org.postgresql.Driver,org.postgresql.Driver@63bfb6]
postgresql: PASSWORD
getConnection returning
driver[className=org.postgresql.Driver,org.postgresql.Driver@63bfb6]
Traceback (innermost last):

java.sql.SQLException: ERROR:  oidin: error in
"\211PNG\015\012\032\012\000\000\000\015IHDR\000\000\003 \000\000\000\

using the secound methode i get more or less the same error:

DriverManager.getConnection("jdbc:postgresql://localhost:5432/sally")
      trying
driver[className=org.postgresql.Driver,org.postgresql.Driver@4cc621]
postgresql: PASSWORD
getConnection returning
driver[className=org.postgresql.Driver,org.postgresql.Driver@4cc621]
Traceback (innermost last):

java.sql.SQLException: ERROR:  oidin: error in
"\211PNG\015\012\032\012\000\000\000\015IHDR\000\000\003
\000\000\000\235\010\006\000\000\001;\313,\310\000\000
\000IDATx\332\354]wx\024\305\

both methode work fine with other jdbc drivers. finally i use the
postgres proprietary methode with the large object manager. this works
fine for a while but gets the error:

NOTICE:  current transaction is aborted, queries ignored until end of
transaction block

SQLWarning: reason(NOTICE:  current transaction is aborted, queries
ignored until end of transaction block
)
Traceback (innermost last):

FastPath-Aufruf ergab »ERROR:  current transaction is aborted, queries
ignored until end of transaction block
«.
          at org.postgresql.fastpath.Fastpath.fastpath(Unknown Source)
          at org.postgresql.fastpath.Fastpath.fastpath(Unknown Source)
          at org.postgresql.fastpath.Fastpath.getInteger(Unknown Source)
          at org.postgresql.largeobject.LargeObjectManager.create(Unknown
Source)
          at de.emdete.sallys.Db.newDocument(Db.java:326)

org.postgresql.util.PSQLException: FastPath-Aufruf ergab »ERROR:
current transaction is aborted, queries ignored until end of transaction
block
«.

  > This might be useful: http://www.j-elite.com/pgprimer , then go to the
  > BLOB section and see if its helps... if not - let me know what would be
  > useful additions in there and I'll add them ;)

okay, i read this. it says that since 7.2 blob and bytea are different
in the way the data is stored. with a table created with type bytea the
jdbc-konform methode work fine. also the FastPath-error didn't show up.

the documentation at http://www.j-elite.com/pgprimer sayes that
setBytes/setBinaryStream can only be used with bytea while setBlob has
to be used with oid. so that ist the cause for my first error. but the
second is still not solved as far i understand.

the samplecode provided uses postgresql methodes to create a blob as i
did. what would be the jdbc-konform way to create a Blob-object?

best regards

    michael








Re: [Fwd: [Fwd: Re: solved: fastpath error?]]

От
Barry Lind
Дата:
Michael,

Thanks for the test case.  I have tracked down the bug.  I will commit a
fix to CVS later today.  The problem was that the LargeObject class had
a finalize() method that called the close() method.  The idea being that
if you never explicitly closed the LargeObject it would take care of
that for you during garbage collection.  The problem was that the scope
of a large object is a transaction, thus once you commit the transaction
the large object is no longer valid.  Thus if the LargeObject was
garbage collected after a commit then the call to close() would error
since the large object handle was no longer valid.  The fix is to just
remove the call to close() in the finalize() method and to let the
server release the resource automatically on transaction commit/rollback.

thanks,
--Barry


M. Dietrich wrote:

 >hi barry,
 >
 >On Wed, Jun 19, 2002 at 02:50:36PM -0700, Barry Lind wrote:
 >
 >
 >>If you could send a test case demonstrating the problem I will look
into it.
 >>
 >>
 >see the source. it shows the error after several inserts on my machine.
 >
 >
 >best regards,
 >
 >    michael
 >
 >
 >------------------------------------------------------------------------
 >
 >public class Test
 >{
 >    public static void main(String[] arg) throws Exception
 >    {
 >
    new org.postgresql.Driver();
 >
    java.sql.DriverManager.setLogWriter(new java.io.PrintWriter(System.err));
 >    java.sql.Connection con =
java.sql.DriverManager.getConnection("jdbc:postgresql://localhost:5432/sally",
"sally", "sally");
 >
    con.setAutoCommit(false);
 >    org.postgresql.largeobject.LargeObjectManager lom =
((org.postgresql.Connection)con).getLargeObjectAPI();
 >
    {
 >
        try // dropping the table
 >
        {
 >
        java.sql.Statement statement = con.createStatement();
 >
            statement.executeUpdate("DROP INDEX MD_ITEST");
 >
            statement.executeUpdate("DROP TABLE MD_TEST");
 >
            java.sql.DriverManager.println("testtable dropped");
 >
        }
 >
        catch (java.sql.SQLException e)
 >
        {
 >
            con.rollback();
 >
        }
 >
        // create a test table
 >
    java.sql.Statement statement = con.createStatement();
 >
        statement.executeUpdate("CREATE TABLE MD_TEST (MD_DOC OID, MD_OID BIGINT
NOT NULL)");
 >
        statement.executeUpdate("CREATE UNIQUE INDEX MD_ITEST ON MD_TEST(MD_OID)");
 >
        java.sql.DriverManager.println("testtable created");
 >
        statement.close();
 >
        con.commit();
 >
    }
 >
    // insert 1000 rows
 >    long i = 0;
 >
    while (i++ < 1000)
 >
    {
 >
        //System.runFinalization(); System.gc(); // comment out these to see the
error even earlier
 >
        java.sql.DriverManager.println("id = " + i);
 >
        // create blob out of class-file (everything else suits fine)
 >
    java.io.InputStream in = new java.io.BufferedInputStream(new
java.io.FileInputStream("Test.class"));
 >
    int loid = lom.create(org.postgresql.largeobject.LargeObjectManager.READ
| org.postgresql.largeobject.LargeObjectManager.WRITE);
 >
        java.sql.DriverManager.println("loid = " + loid);
 >
    org.postgresql.largeobject.LargeObject blob = lom.open(loid,
org.postgresql.largeobject.LargeObjectManager.WRITE);
 >
    int s;
 >
    byte buf[] = new byte[2048];
 >
        while ((s = in.read(buf, 0, buf.length)) > 0)
 >
            blob.write(buf, 0, s);
 >
        blob.close();
 >
        in.close();
 >
        // prepare insert statement
 >
    java.sql.PreparedStatement preparedStatement =
con.prepareStatement("INSERT INTO MD_TEST (MD_OID, MD_DOC) VALUES(?, ?)");
 >
        // bind vars
 >
        preparedStatement.setLong(1, i);
 >
    java.sql.Blob b = new
org.postgresql.largeobject.PGblob((org.postgresql.Connection)con, loid);
 >
        preparedStatement.setBlob(2, b);
 >
        // exec insert
 >
    int no = preparedStatement.executeUpdate();
 >
        preparedStatement.close();
 >
        java.sql.DriverManager.println("row created");
 >
        con.commit(); // move this commit out of the loop and everything's fine...
 >
    }
 >
    con.close();
 >
    java.sql.DriverManager.println("test succeeded");
 >    }
 >}
 >
 >
 >------------------------------------------------------------------------
 >
 ><?xml version="1.0"?>
 ><project name="training" default="all" basedir=".">
 >    <property name="name" value="training" />
 >    <property name="build.compiler" value="modern" />
 >    <target name="all" depends="compile" />
 >    <target name="compile">
 >
    <javac
 >
        srcdir="."
 >
        debug="yes"
 >
        classpath=".:/home/mdt/cd/devpgjdbc2.jar"
 >
    />
 >    </target>
 >    <target name="run" depends="compile">
 >
    <java
 >
        classname="Test"
 >
        fork="yes"
 >
        classpath=".:/home/mdt/cd/devpgjdbc2.jar"
 >
    />
 >    </target>
 >    <target name="javadoc" depends="compile">
 >
    <javadoc
 >
        sourcepath="."
 >
        packagenames="*"
 >
        destdir="javadoc"
 >
    />
 >    </target>
 ></project>
 >
 >