In my J2ee web application I am using a datasource accessed stored in the weblogic server and accessed through jndi. In normal datasource bean declaration there is a property defaultAutoCommit which can be set to false. Is there a similar property or is there a way to set something like this when using datasource in JNDI. Because currently my rollback won't work using JNDI. But when I normally define my datasource in the application context with defaultAutoCommit set to false my rollback works.
JNDI Data source:
<bean id="TerasolunaDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="dataSource" />
</bean>
Normal Data Source defined in application context
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="oracle.jdbc.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:#192.168.178.82:1521:anicom" />
<property name="username" value="jay" />
<property name="password" value="jay" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="defaultAutoCommit" value="false" />
</bean
You need a JTA transaction manager and transaction logic. It's not just auto commit.
Related
I currently having ActiveMQ jetty web server configured by using LDAP authentication for the users of the web console (admins), but I'm struggling to have at the same time HashLoginService for Rest API purpose...
I there a way to have the two authentication methods working on ActiveMQ Jetty?
Here my working config with LDAP:
<bean id="ldapLoginService" class="org.eclipse.jetty.jaas.JAASLoginService">
<property name="name" value="LDAP realm" />
<property name="loginModuleName" value="LDAPLogin" />
<property name="roleClassNames" value="org.apache.activemq.jaas.GroupPrincipal" />
<property name="identityService" ref="identityService" />
</bean>
<bean id="identityService" class="org.eclipse.jetty.security.DefaultIdentityService"/>
<bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC" />
<property name="roles" value="admin_grp" />
<property name="authenticate" value="true" />
</bean>
<bean id="adminSecurityConstraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC" />
<property name="roles" value="admin_grp" />
<property name="authenticate" value="true" />
</bean>
<bean id="securityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="securityConstraint" />
<property name="pathSpec" value="/api/*,/admin/*,*.jsp" />
</bean>
<bean id="adminSecurityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="adminSecurityConstraint" />
<property name="pathSpec" value="*.action" />
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="loginService" ref="ldapLoginService" />
<property name="realmName" value="LdapRealm" />
<property name="identityService" ref="identityService" />
<property name="authenticator">
<bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator" />
</property>
<property name="constraintMappings">
<list>
<ref bean="adminSecurityConstraintMapping" />
<ref bean="securityConstraintMapping" />
</list>
</property>
<property name="handler" ref="secHandlerCollection" />
</bean>
and the ldap config:
LDAPLogin {
org.apache.activemq.jaas.LDAPLoginModule required
debug="false"
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="{{ ldap_connect_url }}"
connectionUsername="{{ bind_dn }}"
connectionPassword="{{ bind_pw }}"
connectionProtocol=""
authentication=simple
userBase="{{ base_dn }}"
userSearchMatching="{{ ldap_user_search_matching }}"
userSearchSubtree="true"
roleBase="{{ ldap_role_base }}"
roleName="cn"
roleSearchMatching="{{ ldap_role_search_matching }}"
roleSearchSubtree=false
;
};
Why don't you add the PropertyFileLoginModule to your JAAS config file? It is similar to the HashLoginService, but works with JAAS. You would have to change your JAAS config to make the LDAPLoginModule sufficient rather than required, and make the PropertyFileLoginModule also sufficient. That way, if either of the login modules can succeed in authenticating the user. Reading more about the definitions of required/requisite/sufficient/optional may be helpful.
Jetty 9.x JAAS docs do not mention the ability to run multiple authentication sources, but you could implement your own custom JAAS LoginModule to support it.
If you are looking for something out-of-the-box, I know many people run ActiveMQ inside another runtime container (such as Apache Karaf) that supports single JAAS realm with multiple backends.
I am publishing message to ActiveMQ queue (TEST.AMQ.QUEUE), which is Bridged to IBM MQ queue (TEST.IBM-MQ.QUEUE) by the following configuration in activmq.xml:
<bean id="remoteFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="username" value="***"></property>
<property name="password" value="***"></property>
<property name="targetConnectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="1*.2*6.**.***" />
<property name="port" value="1*1*" />
<property name="queueManager" value="Q****HUB" />
<property name="channel" value="Q*****D" />
<property name="transportType" value="1" />
</bean>
</property>
</bean>
<!-- Configure JMS bridge -->
<jmsBridgeConnectors>
<jmsQueueConnector outboundQueueConnectionFactory="#remoteFactory">
<outboundQueueBridges>
<outboundQueueBridge outboundQueueName="TEST.IBM-MQ.QUEUE" />
</outboundQueueBridges>
</jmsQueueConnector>
</jmsBridgeConnectors>
I need to set the property TARGCLIENT as MQ, to disable RFH2 headers, how can i provide this property in activemq.xml file, in which my bridge configurations are defined.
The targetClient property can be set on queues, but I'm not sure where it will fit with the bridge.
Could try this name:
queue:///TEST.IBM-MQ.QUEUE?targetClient=1
Or maybe define a bean, and reference that:
<bean id="queue" class="com.ibm.mq.jms.MQQueue"
depends-on="remoteFactory">
<property name="baseQueueManagerName" value="*queue manager*" />
<property name="baseQueueName" value="TEST.IBM-MQ.QUEUE" />
<property name="targetClient" value="1" />
</bean>
I am creating a spring based web application that uses embedded hsqldb.
My spring config is pretty simple:
<jdbc:embedded-database id="dataSource" type="HSQL" >
<jdbc:script location="classpath:scripts/create-table-if-not-exists" />
</jdbc:embedded-database>
But with this config all data is stored in memory. Here is the data source url that is created
jdbc:hsqldb:mem:dataSource
I need to persist data to a file. So that I can use it again after server restart.
This solution worked for me
<bean class="org.apache.commons.dbcp2.BasicDataSource" id="dataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:#{systemProperties['user.home']}/db/data" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:scripts/create-table-if-not-exists" />
</jdbc:initialize-database>
Could you please help to solve the problem with XA transactions on Activemq and Oracle and Bitronix.
I have a activemq and using camel.xml embeded in for routing message from one queue to oracle db.
this is the content of camel.xml file in conf folder of standalone Activemq.
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route id="partnerToDB">
<from uri="activemqXa:example.A" />
<transacted ref="PROPAGATION_REQUIRED"/>
<transform>
<simple>insert into tbl_1(body,type) values('${in.body}','P') </simple>
</transform>
<to uri="jdbc:dataSource" />
</route>
</camelContext>
<!-- TX configuration -->
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="transactionManager"/>
<property name="userTransaction" ref="transactionManager" />
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm" />
</bean>
<bean id="transactionManager" factory-method="getTransactionManager" class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jtaTransactionManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
<!-- JMS configuration -->
<bean id="resourceManager" class="org.apache.activemq.pool.ActiveMQResourceManager" init-method="recoverResource">
<property name="transactionManager" ref="transactionManager" />
<property name="connectionFactory" ref="pooledJmsXaConnectionFactory" />
<property name="resourceName" value="activemq.default,java/testDS1" />
</bean>
<bean id="pooledJmsXaConnectionFactory" class="bitronix.tm.resource.jms.PoolingConnectionFactory" init-method="init" destroy-method="close" >
<property name="className" value="org.apache.activemq.ActiveMQXAConnectionFactory" />
<property name="uniqueName" value="activemq" />
<property name="maxPoolSize" value="8" />
<property name="driverProperties">
<props>
<prop key="brokerURL">tcp://172.16.9.17:61617</prop>
</props>
</property>
</bean>
<bean id="activemqXa" class="org.apache.activemq.camel.component.ActiveMQComponent">
<!-- because of https://issues.apache.org/jira/browse/AMQ-3251, we cannot use the XaPooledConnectionFactory in AMQ 5.5.1 -->
<property name="connectionFactory" ref="pooledJmsXaConnectionFactory"/>
<property name="transacted" value="false"/>
<property name="transactionManager" ref="jtaTransactionManager"/>
</bean>
<!-- JDBC configuration -->
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
init-method="init" destroy-method="close">
<property name="className" value="bitronix.tm.resource.jdbc.lrc.LrcXADataSource" />
<property name="uniqueName" value="java/testDS1" />
<property name="maxPoolSize" value="5" />
<property name="minPoolSize" value="0" />
<property name="allowLocalTransactions" value="false" />
<property name="testQuery" value="SELECT 1 FROM DUAL" />
<property name="driverProperties">
<props>
<prop key="user">test</prop>
<prop key="password">test</prop>
<prop key="url">jdbc:oracle:thin:#db1sh:1521/org.amin.org</prop>
<prop key="driverClassName">oracle.jdbc.OracleDriver</prop>
</props>
</property>
</bean>
when I run Activemq and send a message to example.A queue, nothing is inserted on db and message is dequeued from queue, I get this error in activemq log:
[org.apache.camel.RuntimeCamelException - java.sql.SQLException: cannot commit a resource
enlisted in a global transaction]
Also I have run these SQL scripts for Oracle DataBase:
$ORACLE_HOME/javavm/install/initxa.sql
$ORACLE_HOME/javavm/install/initjvm.sql
and the following grant statments:
grant select on pending_trans$ to public;
grant select on dba_2pc_pending to public;
grant select on dba_pending_transactions to public;
grant execute on dbms_system to <user>;
Any ideas/solutions are welcome!
Thanks
Looking at the first lines in the camel jdbc component docs I find this information box
This component can not be used as a Transactional Client. If you need transaction support in your route, you should use the SQL component instead.
I am searching for a solution, to use Spring (V1.3.2) and NHibernate (V3.2.0) together with the declarative transactionmanagement of Spring to communicate with two independent SQLite database instances.
Currently I can read and write from/to both database instances but the transaction management only works for one database (DbProvider_DB1).
The „why“ is clear for me, but how can I use the declarative transaction management for both databases? Do I need two transaction manager? If yes, how can I define a second one and use it?
Here is my configuration, nothing strange but for the sake of completeness:
dao.xml
<tx:attribute-driven />
<!-- Datenbankprovider -->
<db:provider id="DbProvider_DB1" provider="SQLite-1.0.72" connectionString="Data Source=db1.db3;Version=3;New=False;" />
<db:provider id="DbProvider_DB2" provider="SQLite-1.0.72" connectionString="Data Source=db2.db3;Version=3;New=False;" />
<!-- SessionFactories -->
<object id="SessionFactory" abstract="true" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32">
<property name="HibernateProperties">
<dictionary>...</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
<object id="SessionFactory_DB1" parent="SessionFactory" >
<property name="DbProvider" ref="DbProvider_DB1" />
</object>
<object id="SessionFactory_DB2" parent="SessionFactory" >
<property name="DbProvider" ref="DbProvider_DB2" />
</object>
<!-- Transactionmanager -->
<object id="transactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider_DB1"/>
<property name="SessionFactory" ref="SessionFactory_DB1"/>
<property name="TransactionSynchronization" value="Always"/>
</object>
<!-- Data Access Objects -->
<object id="Dao_DB1" type="Dao1, Dao">
<property name="SessionFactory" ref="SessionFactory_DB1" />
</object>
<object id="Dao_DB2" type="Dao2, Dao">
<property name="SessionFactory" ref="SessionFactory_DB2" />
</object>
Dao
[Transaction]
public TEntity Save( TEntity entity )
{
CurrentSession.Save( entity );
return entity;
}
Thanx
The solution is to use the TxScopeTransactionManager instaed of HibernateTransactionManager.
<object id="transactionManager" type="Spring.Data.Core.TxScopeTransactionManager, Spring.Data">
<property name="TransactionSynchronization" value="Always"/>
</object>