karaf-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Ward <tim.w...@paremus.com>
Subject Re: MariaDB/JPA Transaction rollback not working
Date Fri, 18 May 2018 09:23:44 GMT
Hi Alex,

The bundles you need are listed in the bndrun for the JPA version of the enRoute application,
but as I think you’re using OpenJPA (rather than Hibernate) it may help to explain things
in relation to the Transaction Control JPA integration test for OpenJPA. I’m sure that at
least some of this will be stuff you already know, but I’m trying to make sure I give a
compete explanation. 

This method defines some extra properties to add to the persistence unit. It references a
couple of open bugs in OpenJPA which may or may not affect you. It also adds schema generation
as OpenJPA does not support the standard properties from JPA 2.1 https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L34

This method defines the OpenJPA bundles and their immediate dependencies. https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L48

You then need:

• Aries JPA 2.7.0 - this provides the OSGi JPA Service 1.1 RI (1.1 features are needed by
the Aries Tx Control JPA resource provider to support XA)

• Aries Tx Control Service - either XA or local depending on whether you need XA Transaction
support. For example https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L365

• Aries Tx Control JPA resource provider - either XA or local depending on your needs. Note
that you can’t use the XA provider with the local service, but you can use the local provider
with the XA service (although this doesn’t make a lot of sense to do). For example https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L377

• A JDBC Service implementation supporting your database driver. H2 supports this natively
(which is why it is used in many examples) but MariaDB does not. Therefore you will need to
deploy PAX-JDBC’s support. See https://github.com/ops4j/org.ops4j.pax.jdbc/tree/master/pax-jdbc-mariadb

You then have the option of either programmatically assembling your Resource Provider, or
using configuration. Configuration is generally easier and is what I normally recommend. At
that point you need to create a factory configuration for the relevant PID (it depends on
whether you use the local or XA resource provider, see https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L175)

The necessary configuration properties are:

• url - the JDBC URL for your database 
• osgi.jdbc.driver.class - the database driver class name, in your case org.mariadb.jdbc.Driver
• osgi.unit.name - the name of your persistence unit 

The result of this configuration will be a JPAEntityManagerProvider service registered in
the service registry (using your EntityManagerFactoryBuilder and the MariaDB DataSourceFactory).
You can then Inject that service into your code and combine it with the TransactionControl
service to make a thread safe EntityManager that you can use in all your requests (just like
the enRoute example does). 

I hope this helps,


Sent from my iPhone

> On 17 May 2018, at 22:46, Alex Soto <alex.soto@envieta.com> wrote:
> Thanks Tim, 
> I was using branch R7, changed to master, it builds now.
> Now I have updated my project to OSGi 7 with Transaction Control, how do I deploy to
> i.e., what bundles/features do I need?
> Best regards,
> Alex soto
>> On May 17, 2018, at 2:08 PM, Tim Ward <tim.ward@paremus.com> wrote:
>> Hi Alex,
>> Bnd 4.0.0 was only released last Sunday, but this should have been changed yesterday
in this commit https://github.com/osgi/osgi.enroute/commit/9f9857c3d317cd08a7aaf7327c1904676299f9ee
to make sure enRoute kept building. 
>> EnRoute is automatically pushed to the sonatype OSGi nexus repository, so is it possible
that you’re running offline, or firewalled from the repo? You should be able to force snapshot
updates from the Maven command line. 
>> Best Regards,
>> Tim
>> Sent from my iPhone
>>> On 17 May 2018, at 18:26, Alex Soto <alex.soto@envieta.com> wrote:
>>> Allright,  I am trying to follow the EnRoute tutorial.
>>> I am getting this error:
>>> [ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies
could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT
in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/)
-> [Help 1]
>>> Any idea (time frame) when this will move from SNAPSHOT dependencies?
>>> Best regards,
>>> Alex soto
>>>> On May 17, 2018, at 11:08 AM, Tim Ward <tim.ward@paremus.com> wrote:
>>>> It is highly unlikely that you’ll hit the same issues. The transaction
control resource provider uses the DataSourceFactory directly to create a DataSource (either
progamatically using a factory service or via config admin) that enlists itself in the ongoing
transaction. This means that the answer to your question is “with Transaction Control you
don’t have to do that because it does it automatically”
>>>> If you want to use XA transactions then the only requirement is that the
DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API
to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource
provider implementation.
>>>> Best Regards,
>>>> Tim
>>>> Sent from my iPhone
>>>>> On 17 May 2018, at 15:17, Alex Soto <alex.soto@envieta.com> wrote:
>>>>> I will take a look at these examples.
>>>>> However, I think that if I cannot get a MariaDB DataSource that supports
transactions, then it will still not work, right?
>>>>> If the examples use H2 database, I still may get different results when
I change to MariaDB, and I will find myself in the same spot as of now.
>>>>> So, the question remains about what is the correct way how to register
a transaction aware MariaDB DataSource.
>>>>> Best regards,
>>>>> Alex soto
>>>>>> On May 17, 2018, at 1:46 AM, Tim Ward <tim.ward@paremus.com>
>>>>>> The best place to start when looking for OSGi R7 examples is the
enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building
applications using R7 specifications. 
>>>>>> https://enroute.osgi.org
>>>>>> Most of the projects in use are just new versions of long established
OSGi implementations from Aries and Felix. The majority of them are already released and in
Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS
whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations
that require R7 framework features, so all of them should run on Karaf.
>>>>>> Best Regards,
>>>>>> Tim
>>>>>> Sent from my iPhone
>>>>>>> On 16 May 2018, at 22:25, Alex Soto <alex.soto@envieta.com>
>>>>>>> I agree, it s very frustrating and time consuming. Almost impossible
to get it right.
>>>>>>> I may try the OSGi R7, but I am not sure of its adoption level
at this time, availability of bundles, examples, support by Karaf, etc.
>>>>>>> Anyway, back to my current stack.  I only see one DataSource
being registered:
>>>>>>> karaf@root()> service:list DataSource
>>>>>>> [javax.sql.DataSource]
>>>>>>> ----------------------
>>>>>>>  databaseName = responder
>>>>>>>  dataSourceName = responder
>>>>>>>  osgi.jdbc.driver.name = mariadb
>>>>>>>  osgi.jndi.service.name = responder
>>>>>>>  service.bundleid = 14
>>>>>>>  service.factoryPid = org.ops4j.datasource
>>>>>>>  service.id = 194
>>>>>>>  service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
>>>>>>>  service.scope = singleton
>>>>>>>  url = jdbc:mariadb:XXXXXX
>>>>>>> Provided by : 
>>>>>>>  OPS4J Pax JDBC Config (14)
>>>>>>> Used by: 
>>>>>>>  Data (135)
>>>>>>> Not sure what to do with this.  
>>>>>>> I specified the following in the configuration:
>>>>>>> pool=narayana
>>>>>>> xa=true
>>>>>>> Best regards,
>>>>>>> Alex soto
>>>>>>>> On May 16, 2018, at 4:12 PM, Tim Ward <tim.ward@paremus.com>
>>>>>>>> The structure of the JNDI name is defined by the JNDI service
>>>>>>>> osgi:service/<interface name>[/<filter>]
>>>>>>>> So in this case both of your services should be DataSource
instances, but they should have different filters. 
>>>>>>>> The important thing is to make sure you have an JTA enlisting
DataSource registered as a service (this isn’t just your normal DataSource), then to build
a filter which selects that. One option for this is to use the enlistment whiteboard from
Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc
>>>>>>>> This is a non-trivial thing to do, which is why I keep mentioning
Transaction Control which handles the enlistment reliably without the layers of services.

>>>>>>>> Best Regards,
>>>>>>>> Tim
>>>>>>>> Sent from my iPhone
>>>>>>>>> On 16 May 2018, at 21:57, Alex Soto <alex.soto@envieta.com>
>>>>>>>>> Thank you Tim.
>>>>>>>>> Any idea what the JNDI names would be?
>>>>>>>>> It is Pax-JDBC creating these JNDI names, so I have no
>>>>>>>>> From the Karaf console:
>>>>>>>>> karaf@root()> jndi:names 
>>>>>>>>> JNDI Name              │ Class Name
>>>>>>>>> ───────────────────────┼───────────────────────────────────────────────
>>>>>>>>> osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
>>>>>>>>> osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl
>>>>>>>>> Best regards,
>>>>>>>>> Alex soto
>>>>>>>>>> On May 16, 2018, at 3:48 PM, Tim Ward <tim.ward@paremus.com>
>>>>>>>>>> Just looking quickly. 
>>>>>>>>>> You have the same JNDI name for both JTA and non
JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted
in the Transaction and not enlisted. The comments also indicate a misunderstanding of the
purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things
like sequence allocation and out of band optimisations). You really do need to have both and
they do need to behave differently.
>>>>>>>>>> At a guess your DataSource is not enlisted with the
transaction manager present in the system.  This usually happens by configuring a (otherwise
invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking
that it does) hence your transactions would be broken. This is one of the several reasons
I try to direct people to Transaction Control where the model actively pushes you toward transactions
that actually work, rather than hiding all the magic behind an annotation.
>>>>>>>>>> Hopefully this gives you some clues as to what might
be wrong. 
>>>>>>>>>> Best Regards,
>>>>>>>>>> Tim
>>>>>>>>>> Sent from my iPhone
>>>>>>>>>>> On 16 May 2018, at 21:34, Jean-Baptiste Onofré
<jb@nanthrax.net> wrote:
>>>>>>>>>>> Are you sure about your code ? Flush looks weird
to me and it seems you don't use container managed transaction.
>>>>>>>>>>> Regards
>>>>>>>>>>> JB
>>>>>>>>>>>> On 16/05/2018 21:08, Alex Soto wrote:
>>>>>>>>>>>> Yes, same result.  I even tried with Narayana
Transaction Manager, and same result.
>>>>>>>>>>>> Best regards,
>>>>>>>>>>>> Alex soto
>>>>>>>>>>>>> On May 16, 2018, at 2:56 PM, Jean-Baptiste
Onofré <jb@nanthrax.net <mailto:jb@nanthrax.net>> wrote:
>>>>>>>>>>>>> Same behavior with RequiresNew ?
>>>>>>>>>>>>> Regards
>>>>>>>>>>>>> JB
>>>>>>>>>>>>>> On 16/05/2018 19:44, Alex Soto wrote:
>>>>>>>>>>>>>> With Karaf version 4.2.0, Rollback
is not working with MariaDB and InnoDB tables.
>>>>>>>>>>>>>> I deployed these features (from Karaf’s
enterprise  repository):
>>>>>>>>>>>>>> <feature>aries-blueprint</feature>
>>>>>>>>>>>>>> <feature>transaction</feature>
>>>>>>>>>>>>>> <feature>jndi</feature>
>>>>>>>>>>>>>> <feature>jdbc</feature>
>>>>>>>>>>>>>> <feature>jpa</feature>
>>>>>>>>>>>>>> <feature>pax-jdbc-mariadb</feature>
>>>>>>>>>>>>>>        <feature>pax-jdbc-config</feature>
>>>>>>>>>>>>>> <feature>pax-jdbc-pool-dbcp2</feature>
>>>>>>>>>>>>>> <feature>hibernate</feature>
>>>>>>>>>>>>>> My Data Source is configured in the
file /org.ops4j.datasource-responder.cfg/
>>>>>>>>>>>>>>   osgi.jdbc.driver.name = mariadb
>>>>>>>>>>>>>>   dataSourceName=responder
>>>>>>>>>>>>>>   url
>>>>>>>>>>>>>>   = jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>>>>>>>>>>>>>>   user=XXXX
>>>>>>>>>>>>>>   password=XXXX
>>>>>>>>>>>>>>   databaseName=responder
>>>>>>>>>>>>>>   #Pool Config
>>>>>>>>>>>>>>   pool=dbcp2
>>>>>>>>>>>>>>   xa=true
>>>>>>>>>>>>>> My persistence.xml:
>>>>>>>>>>>>>>   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>>>>>>>>>>>>>>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>>>>>>>        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>>>>>>>>>>>>>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>>>>>>>>>>>>>>            <persistence-unit name="responderPersistenUnit"
>>>>>>>>>>>>>>                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>>>>>>>>>>>>>>            <!-- Only used when
transaction-type=JTA -->
>>>>>>>>>>>>>>                <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>>>>>>>>>>>>>>            <!-- Only used when
transaction-type=RESOURCE_LOCAL -->
>>>>>>>>>>>>>>                <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>>>>>>>>>>>>>>            <properties>
>>>>>>>>>>>>>>                    <property name=“hibernate.dialect"
value="org.hibernate.dialect.MySQL5Dialect" />
>>>>>>>>>>>>>>                <property name="hibernate.show_sql"
value="true" />
>>>>>>>>>>>>>>                <property name="hibernate.format_sql"
value="true" />
>>>>>>>>>>>>>>                <property name="hibernate.hbm2ddl.auto"
>>>>>>>>>>>>>>            </properties>
>>>>>>>>>>>>>>        </persistence-unit>
>>>>>>>>>>>>>>   </persistence>
>>>>>>>>>>>>>> My blueprint.xml:
>>>>>>>>>>>>>>   <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>>>>>>>>>>>>>>   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>>>>>>>>>>>>>>   xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>>>>>>>>>>>>>>   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>>>>>>>   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>>>>>>>>>>>>>> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>>>>>>>>>>>>>>   <jpa:enable />
>>>>>>>>>>>>>>   <tx:enable />
>>>>>>>>>>>>>>   <bean id="userService" class="org.data.impl.UserServiceImpl"
>>>>>>>>>>>>>>   <service ref="userService" interface="org.data.UserService"
>>>>>>>>>>>>>>   </blueprint>
>>>>>>>>>>>>>> For testing I throw exception in
my DAO:
>>>>>>>>>>>>>> @Transactional(REQUIRED)
>>>>>>>>>>>>>> public void addUser(User user) {
>>>>>>>>>>>>>> em.persist(user);
>>>>>>>>>>>>>> em.flush();
>>>>>>>>>>>>>> throw new RuntimeException("On Purpose");
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>> I expect the record not to be in
the table due to rollback of the transaction, but it still shows up in my database table.
>>>>>>>>>>>>>> Best regards,
>>>>>>>>>>>>>> Alex soto

View raw message