You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jackrabbit.apache.org by Gamba <ho...@handelshof.de> on 2009/09/10 09:29:43 UTC

Confirming assumptions about transactional environment and session-handling

Hi,

I need some help confirming some assumptions about jackrabbit in a
transactional environment with jboss.

I need to verify some points to find some problems with concurrent updates
in my code.

I'm running jackrabbit 1.6.0 on jboss 4.2.3 with mysql at the backend. All
the code to access the jackrabbit-api is placed in a stateless session bean,
in different methods (add node, delete node, ...). I'm using container
managed transaction with tx_required on each method. Each method are using
an own
session with a technical user (the same in all methods) to read/write access
jackrabbit. The session logout() method is called in a finally { .. } blocj
at the end of each method. 
I have own node-types for nodes and files.

1) First of all I want to know if this is a common scenario or are there any
known problems regarding
the environment?

After implementing this I'm reading something about locks and concurrent
updates and asks myself
If I need the mixin-typ mix:lockable for my own nodes. After reading the
Spec 8.4.10 I think I don't need 
the mixin types and did not handle manually node-locking, because I'm
working in a transactional environment: 

"As a result, if a lock is enabled and then disabled within the same
transaction, its effect never makes it to the persistent workspace and
therefore it does nothing. In order to use locks properly (that is, to
prevent the “lost update problem”), locking and unlocking must be done in
separate
transactions."

2) Is it correct that I need not bother with such locking issues?

3) So I did not expect an InvalidItemStateExcpeton?

4) Have I call the session.save() method inside my method-transactions. Or
is it saved automatically
on a the transaction-commit?

5) Are there any known session-complications with only one technical user in
this environment?

Ok, so far, to get a feeling for my code ... 

Thx
Gamba



-- 
View this message in context: http://www.nabble.com/Confirming-assumptions-about-transactional-environment-and-session-handling-tp25378625p25378625.html
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: Confirming assumptions about transactional environment and session-handling

Posted by Guo Du <mr...@gmail.com>.
On Thu, Sep 10, 2009 at 2:43 PM, Alexander Klimetschek <ak...@day.com> wrote:
> JCR is more designed to log in with the "real" users and not use a
> technical user like it's typical with relational databases.

Security/Access control could be very complex in real life. Such as
user may only able to READ some of the node in the workspace.
Technical user may be easier to manage like a database, and leave the
business application to manage the complexity.

--Guo

Re: Confirming assumptions about transactional environment and session-handling

Posted by Gamba <ho...@handelshof.de>.
Ok, I found the mistake with the session auto-commit problem ... I guess ... 
:-)

I had two datasources accessing the datastore. One is configured in the
repository and I configured 
an other, which was referenced from repository.xml (to reference the user
name by jndi I think). It was a piece of testcode from my early days with
jackrabbit. After referencing the datastore directly from repository.xml and
deleting the additional datasource there are no more strange "set
auto-commit .." exceptions. 

Thx so far,
Gamba




Gamba wrote:
> 
> version 1.6.0. reproducing it not easy, bit sometimes with multiple
> threads the exception occurs.
> 
> 
> 
> Alexander Klimetschek wrote:
>> 
>> On Fri, Sep 11, 2009 at 10:01, Gamba <ho...@handelshof.de> wrote:
>>> 09:52:22,984 WARN  [DbDataStore] Can not insert new record
>>> java.sql.SQLException: You cannot set autocommit during a managed
>>> transaction!
>>>        at
>>> org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:582)
>>>        at
>>> org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:458)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.setupConnection(ConnectionRecoveryManager.java:341)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.reestablishConnection(ConnectionRecoveryManager.java:409)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.getConnection(ConnectionRecoveryManager.java:159)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:293)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:261)
>>>        at
>>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:239)
>>>        at
>>> org.apache.jackrabbit.core.data.db.DbDataStore.addRecord(DbDataStore.java:314)
>>>        at
>>> org.apache.jackrabbit.core.value.BLOBInDataStore.getInstance(BLOBInDataStore.java:128)
>>>        at
>>> org.apache.jackrabbit.core.value.InternalValue.getBLOBFileValue(InternalValue.java:658)
>>>        at
>>> org.apache.jackrabbit.core.value.InternalValue.create(InternalValue.java:141)
>>>        at
>>> org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:617)
>>>        at
>>> org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:533)
>>>        at
>>> org.apache.jackrabbit.core.NodeImpl.setProperty(NodeImpl.java:2522)
>>>        at
>>> de.handelshof.por.ejb.service.jcr.HMGJCRUserServiceBean.importFile(HMGJCRUserServiceBean.java:569)
>>> ...
>> 
>> Sounds like https://issues.apache.org/jira/browse/JCR-1013 but for the
>> DbDataStore. What version of Jackrabbit are you using? JCR-1013 should
>> be fixed since 1.4.
>> 
>> Regards,
>> Alex
>> 
>> -- 
>> Alexander Klimetschek
>> alexander.klimetschek@day.com
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Confirming-assumptions-about-transactional-environment-and-session-handling-tp25378625p25449484.html
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: Confirming assumptions about transactional environment and session-handling

Posted by Gamba <ho...@handelshof.de>.
version 1.6.0. reproducing it not easy, bit sometimes with multiple threads
the exception occurs.



Alexander Klimetschek wrote:
> 
> On Fri, Sep 11, 2009 at 10:01, Gamba <ho...@handelshof.de> wrote:
>> 09:52:22,984 WARN  [DbDataStore] Can not insert new record
>> java.sql.SQLException: You cannot set autocommit during a managed
>> transaction!
>>        at
>> org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:582)
>>        at
>> org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:458)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.setupConnection(ConnectionRecoveryManager.java:341)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.reestablishConnection(ConnectionRecoveryManager.java:409)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.getConnection(ConnectionRecoveryManager.java:159)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:293)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:261)
>>        at
>> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:239)
>>        at
>> org.apache.jackrabbit.core.data.db.DbDataStore.addRecord(DbDataStore.java:314)
>>        at
>> org.apache.jackrabbit.core.value.BLOBInDataStore.getInstance(BLOBInDataStore.java:128)
>>        at
>> org.apache.jackrabbit.core.value.InternalValue.getBLOBFileValue(InternalValue.java:658)
>>        at
>> org.apache.jackrabbit.core.value.InternalValue.create(InternalValue.java:141)
>>        at
>> org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:617)
>>        at
>> org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:533)
>>        at
>> org.apache.jackrabbit.core.NodeImpl.setProperty(NodeImpl.java:2522)
>>        at
>> de.handelshof.por.ejb.service.jcr.HMGJCRUserServiceBean.importFile(HMGJCRUserServiceBean.java:569)
>> ...
> 
> Sounds like https://issues.apache.org/jira/browse/JCR-1013 but for the
> DbDataStore. What version of Jackrabbit are you using? JCR-1013 should
> be fixed since 1.4.
> 
> Regards,
> Alex
> 
> -- 
> Alexander Klimetschek
> alexander.klimetschek@day.com
> 
> 

-- 
View this message in context: http://www.nabble.com/Confirming-assumptions-about-transactional-environment-and-session-handling-tp25378625p25397371.html
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: Confirming assumptions about transactional environment and session-handling

Posted by Alexander Klimetschek <ak...@day.com>.
On Fri, Sep 11, 2009 at 10:01, Gamba <ho...@handelshof.de> wrote:
> 09:52:22,984 WARN  [DbDataStore] Can not insert new record
> java.sql.SQLException: You cannot set autocommit during a managed
> transaction!
>        at
> org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:582)
>        at
> org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:458)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.setupConnection(ConnectionRecoveryManager.java:341)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.reestablishConnection(ConnectionRecoveryManager.java:409)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.getConnection(ConnectionRecoveryManager.java:159)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:293)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:261)
>        at
> org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:239)
>        at
> org.apache.jackrabbit.core.data.db.DbDataStore.addRecord(DbDataStore.java:314)
>        at
> org.apache.jackrabbit.core.value.BLOBInDataStore.getInstance(BLOBInDataStore.java:128)
>        at
> org.apache.jackrabbit.core.value.InternalValue.getBLOBFileValue(InternalValue.java:658)
>        at
> org.apache.jackrabbit.core.value.InternalValue.create(InternalValue.java:141)
>        at org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:617)
>        at org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:533)
>        at org.apache.jackrabbit.core.NodeImpl.setProperty(NodeImpl.java:2522)
>        at
> de.handelshof.por.ejb.service.jcr.HMGJCRUserServiceBean.importFile(HMGJCRUserServiceBean.java:569)
> ...

Sounds like https://issues.apache.org/jira/browse/JCR-1013 but for the
DbDataStore. What version of Jackrabbit are you using? JCR-1013 should
be fixed since 1.4.

Regards,
Alex

-- 
Alexander Klimetschek
alexander.klimetschek@day.com

Re: Confirming assumptions about transactional environment and session-handling

Posted by Gamba <ho...@handelshof.de>.
Ok, thanks guys. I think my environment, as shown, is correct.

Now one of the real exception I get during my tests. In some of my tests
with mutliple parallel threads I'm calling my stateless-session-bean an get
with 2 or more users the following exception:

...
09:52:11,968 ERROR [ConnectionRecoveryManager] failed to close connection,
reason: You cannot rollback during a managed transaction!, state/code:
null/0
09:52:12,468 ERROR [ConnectionRecoveryManager] failed to close connection,
reason: You cannot rollback during a managed transaction!, state/code:
null/0
09:52:12,468 ERROR [ConnectionRecoveryManager] could not execute statement,
reason: You cannot set autocommit during a managed transaction!, state/code:
null/0
09:52:22,984 ERROR [ConnectionRecoveryManager] could not execute statement,
reason: You cannot set autocommit during a managed transaction!, state/code:
null/0
09:52:22,984 WARN  [DbDataStore] Can not insert new record
java.sql.SQLException: You cannot set autocommit during a managed
transaction!
	at
org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:582)
	at
org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:458)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.setupConnection(ConnectionRecoveryManager.java:341)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.reestablishConnection(ConnectionRecoveryManager.java:409)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.getConnection(ConnectionRecoveryManager.java:159)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmtInternal(ConnectionRecoveryManager.java:293)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:261)
	at
org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.executeStmt(ConnectionRecoveryManager.java:239)
	at
org.apache.jackrabbit.core.data.db.DbDataStore.addRecord(DbDataStore.java:314)
	at
org.apache.jackrabbit.core.value.BLOBInDataStore.getInstance(BLOBInDataStore.java:128)
	at
org.apache.jackrabbit.core.value.InternalValue.getBLOBFileValue(InternalValue.java:658)
	at
org.apache.jackrabbit.core.value.InternalValue.create(InternalValue.java:141)
	at org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:617)
	at org.apache.jackrabbit.core.PropertyImpl.setValue(PropertyImpl.java:533)
	at org.apache.jackrabbit.core.NodeImpl.setProperty(NodeImpl.java:2522)
	at
de.handelshof.por.ejb.service.jcr.HMGJCRUserServiceBean.importFile(HMGJCRUserServiceBean.java:569)
...
09:52:22,984 WARN  [DbDataStore] Can not insert new record
org.apache.jackrabbit.core.data.DataStoreException: Can not insert new
record: You cannot set autocommit during a managed transaction!: You cannot
set autocommit during a managed transaction!
	at
org.apache.jackrabbit.core.data.db.DbDataStore.convert(DbDataStore.java:698)
	at
org.apache.jackrabbit.core.data.db.DbDataStore.addRecord(DbDataStore.java:324)
	at
org.apache.jackrabbit.core.value.BLOBInDataStore.getInstance(BLOBInDataStore.java:128)
	at
org.apache.jackrabbit.core.value.InternalValue.getBLOBFileValue(InternalValue.java:658)
...
Caused by: java.sql.SQLException: You cannot set autocommit during a managed
transaction!
	at
org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:582)
	at
org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:458)


It occurs during a file import. The line in my code whre it occurs is the
following:

...
resNode.setProperty("jcr:data", new ByteArrayInputStream(file.getData()));
...

I'm not setting autocommit anywhere in the code, maybe some jackrabbit code
is setting some properties ... ? I did not know where to search for the
error ... any help would be highly appreciated


Regards,
Gamba
-- 
View this message in context: http://www.nabble.com/Confirming-assumptions-about-transactional-environment-and-session-handling-tp25378625p25396705.html
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: Confirming assumptions about transactional environment and session-handling

Posted by Alexander Klimetschek <ak...@day.com>.
On Thu, Sep 10, 2009 at 14:43, Gamba <ho...@handelshof.de> wrote:
> Hm. I thought, in a transactional environment the locks are released on
> a session commit when I use session-scoped locks and I thought that's the
> only
> useful thing in that case.
>
> So I wonder if I need any locking in my environment?

Well, that simply depends if your application logic requires locking.

> And that the reason I thought there will not be such exceptions,
> because all changes are persisted at commit-time. Hm ... ok,
> when another session updates the same node, then the exception
> could occur ... Is it possible to use refresh() in that case, before
> saving the session?

No, because refresh(true) in Jackrabbit will have no effect (because
Jackrabbit employs copy-on-write) and refresh(false) would discard the
changes of your session.

> At the moment, we have only one and same user for all session-logins calling
> ...
> repository.login(new SimpleCredentials("technical", "passwd".toCharArray()),
> "default");

JCR is more designed to log in with the "real" users and not use a
technical user like it's typical with relational databases.

>
> We ware in test-state at the moment and not in production with our
> application.
> But in production I think we need also only one user, because our
> authentication-access
> is done in a speparate component. So are there any problems which can occur
> with only one user
> to acces jackrabbit with multiple thread calling staless-sb-methods and each
> method
> getting the session with the shown statement?

It's the session that counts, not the user. If you have two sessions,
they can conflict, but this has nothing do to what the users behind
the session are.
Regards,
Alex

-- 
Alexander Klimetschek
alexander.klimetschek@day.com

Re: Confirming assumptions about transactional environment and session-handling

Posted by Gamba <ho...@handelshof.de>.

Alexander Klimetschek wrote:
> 
>> 2) Is it correct that I need not bother with such locking issues?
> 
>> Only if you want to set locks. Otherwise you just have to be aware
>> that an exception might occur because a node has been locked by
>> another session (if that can be the case). With transactions, I think
>> you will get this exception on commit.
> 

Hm. I thought, in a transactional environment the locks are released on
a session commit when I use session-scoped locks and I thought that's the
only
useful thing in that case.

So I wonder if I need any locking in my environment?



Alexander Klimetschek wrote:
> 
>> 3) So I did not expect an InvalidItemStateExcpeton?
> Sorry, I don't understand what you mean by this question?
> 

And that the reason I thought there will not be such exceptions,
because all changes are persisted at commit-time. Hm ... ok,
when another session updates the same node, then the exception
could occur ... Is it possible to use refresh() in that case, before
saving the session?




Alexander Klimetschek wrote:
> 
>> 5) Are there any known session-complications with only one technical user
>> in
>> this environment?
> What do you mean by "only one technical user"?
> 

At the moment, we have only one and same user for all session-logins calling
...
repository.login(new SimpleCredentials("technical", "passwd".toCharArray()),
"default");

We ware in test-state at the moment and not in production with our
application.
But in production I think we need also only one user, because our
authentication-access 
is done in a speparate component. So are there any problems which can occur
with only one user
to acces jackrabbit with multiple thread calling staless-sb-methods and each
method 
getting the session with the shown statement?

Thx
Gamba




-- 
View this message in context: http://www.nabble.com/Confirming-assumptions-about-transactional-environment-and-session-handling-tp25378625p25382645.html
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: Confirming assumptions about transactional environment and session-handling

Posted by Alexander Klimetschek <ak...@day.com>.
On Thu, Sep 10, 2009 at 09:29, Gamba <ho...@handelshof.de> wrote:
> I'm running jackrabbit 1.6.0 on jboss 4.2.3 with mysql at the backend. All
> the code to access the jackrabbit-api is placed in a stateless session bean,
> in different methods (add node, delete node, ...). I'm using container
> managed transaction with tx_required on each method. Each method are using
> an own
> session with a technical user (the same in all methods) to read/write access
> jackrabbit. The session logout() method is called in a finally { .. } blocj
> at the end of each method.
> I have own node-types for nodes and files.
>
> 1) First of all I want to know if this is a common scenario or are there any
> known problems regarding
> the environment?

Typically it's good to have one session per request. This keeps things
simple: there is one login per user and the whole request
automatically one transaction (even if you don't use java tx) if you
have a single sesison.save() at the end of the request. Apache Sling
for example works that way and does authentication handling and
session login for you and simply passes that to servlets. But of
course there are cases where you want more fine control or you need to
handle it more specific if you have parts that will belong to a
distributed transaction.

> After implementing this I'm reading something about locks and concurrent
> updates and asks myself
> If I need the mixin-typ mix:lockable for my own nodes. After reading the
> Spec 8.4.10 I think I don't need
> the mixin types and did not handle manually node-locking, because I'm
> working in a transactional environment:
>
> "As a result, if a lock is enabled and then disabled within the same
> transaction, its effect never makes it to the persistent workspace and
> therefore it does nothing. In order to use locks properly (that is, to
> prevent the “lost update problem”), locking and unlocking must be done in
> separate
> transactions."
>
> 2) Is it correct that I need not bother with such locking issues?

Only if you want to set locks. Otherwise you just have to be aware
that an exception might occur because a node has been locked by
another session (if that can be the case). With transactions, I think
you will get this exception on commit.

> 3) So I did not expect an InvalidItemStateExcpeton?

Sorry, I don't understand what you mean by this question?

> 4) Have I call the session.save() method inside my method-transactions. Or
> is it saved automatically
> on a the transaction-commit?

You have to call it yourself, it's not done automatically. That would
be crazy. The only important thing to note is that when transactions
are enabled, a session save won't persist the data as it is the case
w/o transactions. This will be postponed to the (successful) commit of
the transaction.

> 5) Are there any known session-complications with only one technical user in
> this environment?

What do you mean by "only one technical user"?

Regards,
Alex

-- 
Alexander Klimetschek
alexander.klimetschek@day.com