[JBoss Cache Users] - NullPointerException in replication (GlobalTransaction lost)
by chtimi2
I have a strange problem when i try to have both replication and transactions. Each works fine individually, for transactions i use a JTA impl (Atomikos).
It seems to happen when JBC tries to replicate a change, but not any change: there are changes that are replicated correctly, within a transaction.
I can't post the OK and KO cases because that would be too much code, i'm looking for hints here and will post more if requested.
Hopefully this exception will recall someone something.
Looking at the JBC source, the problem that:
TxInterceptor.visitPrepareCommand ( InvocationContext ctx , PrepareCommand command)
| GlobalTransaction gtx = ctx.getGlobalTransaction; //THIS IS NULL!!!!
|
I've made sure the transaction context has been initiated (with Spring's TransactionSynchronizationManager.isActualTransactionActive) but this seems to be saying that it has been lost along the way.
The stack:
________FF__________ReplicatedComponentGlue/addRemoteInvocation/0/isActualTransactionActive: true
| [org.jboss.cache.interceptors.TxInterceptor][RMI TCP Connection(3)-127.0.0.1] - Caught exception, will now set transaction to roll back
| java.lang.NullPointerException
| at org.jboss.cache.interceptors.TxInterceptor.visitPrepareCommand(TxInterceptor.java:132)
| at org.jboss.cache.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:68)
| at org.jboss.cache.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)
| at org.jboss.cache.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:131)
| at org.jboss.cache.commands.AbstractVisitor.visitPrepareCommand(AbstractVisitor.java:140)
| at org.jboss.cache.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:68)
| at org.jboss.cache.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:116)
| at org.jboss.cache.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:178)
| at org.jboss.cache.interceptors.InvocationContextInterceptor.visitPrepareCommand(InvocationContextInterceptor.java:106)
| at org.jboss.cache.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:68)
| at org.jboss.cache.interceptors.InterceptorChain.invokeRemote(InterceptorChain.java:316)
| at org.jboss.cache.commands.remote.ReplicateCommand.processSingleCommand(ReplicateCommand.java:139)
| at org.jboss.cache.commands.remote.ReplicateCommand.perform(ReplicateCommand.java:115)
| at org.jboss.cache.marshall.CommandAwareRpcDispatcher.executeCommand(CommandAwareRpcDispatcher.java:319)
| at org.jboss.cache.marshall.CommandAwareRpcDispatcher.handle(CommandAwareRpcDispatcher.java:246)
| at org.jgroups.blocks.RequestCorrelator.handleRequest(RequestCorrelator.java:637)
| at org.jgroups.blocks.RequestCorrelator.receiveMessage(RequestCorrelator.java:545)
| at org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:368)
| at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:775)
| at org.jgroups.JChannel.up(JChannel.java:1274)
| at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:462)
| at org.jgroups.protocols.pbcast.STATE_TRANSFER.up(STATE_TRANSFER.java:144)
| at org.jgroups.protocols.FRAG2.up(FRAG2.java:192)
| at org.jgroups.protocols.FC.up(FC.java:468)
| at org.jgroups.protocols.pbcast.GMS.up(GMS.java:796)
| at org.jgroups.protocols.VIEW_SYNC.up(VIEW_SYNC.java:192)
| at org.jgroups.protocols.pbcast.STABLE.up(STABLE.java:233)
| at org.jgroups.protocols.UNICAST.up(UNICAST.java:299)
| at org.jgroups.protocols.pbcast.NAKACK.handleMessage(NAKACK.java:873)
| at org.jgroups.protocols.pbcast.NAKACK.up(NAKACK.java:705)
| at org.jgroups.protocols.BARRIER.up(BARRIER.java:136)
| at org.jgroups.protocols.VERIFY_SUSPECT.up(VERIFY_SUSPECT.java:167)
| at org.jgroups.protocols.FD.up(FD.java:284)
| at org.jgroups.protocols.FD_SOCK.up(FD_SOCK.java:308)
| at org.jgroups.protocols.MERGE2.up(MERGE2.java:144)
| at org.jgroups.protocols.Discovery.up(Discovery.java:263)
| at org.jgroups.protocols.PING.up(PING.java:270)
| at org.jgroups.protocols.TP.passMessageUp(TP.java:1277)
| at org.jgroups.protocols.TP.access$100(TP.java:49)
| at org.jgroups.protocols.TP$IncomingPacket.handleMyMessage(TP.java:1830)
| at org.jgroups.protocols.TP$IncomingPacket.run(TP.java:1804)
| at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
| at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
| at java.lang.Thread.run(Thread.java:619)
What seems strange is that this stack at no point refers to user code. Strange since i used synchronous replication, but maybe the problem comes from that if JBC looks for the transaction context in a ThreadLocal or something like that?
The conf:
<?xml version="1.0" encoding="UTF-8"?>
| <jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">
| <locking
| isolationLevel="READ_COMMITTED"
| lockParentForChildInsertRemove="false"
| lockAcquisitionTimeout="20000"
| nodeLockingScheme="mvcc"
| writeSkewCheck="false"
| concurrencyLevel="500"/>
| <clustering mode="replication">
| <jgroupsConfig configFile="udp.xml" />
| <sync />
| </clustering>
| </jbosscache>
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4268575#4268575
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4268575
16 years, 4 months
[JBoss Cache Users] - Re: MVCC leading to deadlocks in synchronous replication mod
by veklov
As I understand your scenario is not primary use case for JBossCache. People from Hibernate brought up this issue some time ago and as the result the method putForExternalRead was added:
/**
| * Under special operating behavior, associates the value with the specified key for a node identified by the Fqn passed in.
| * <ul>
| * <li> Only goes through if the node specified does not exist; no-op otherwise.</i>
| * <li> Force asynchronous mode for replication to prevent any blocking.</li>
| * <li> invalidation does not take place. </li>
| * <li> 0ms lock timeout to prevent any blocking here either. If the lock is not acquired, this method is a no-op, and swallows the timeout exception.</li>
| * <li> Ongoing transactions are suspended before this call, so failures here will not affect any ongoing transactions.</li>
| * <li> Errors and exceptions are 'silent' - logged at a much lower level than normal, and this method does not throw exceptions</li>
| * </ul>
| * This method is for caching data that has an external representation in storage, where, concurrent modification and
| * transactions are not a consideration, and failure to put the data in the cache should be treated as a 'suboptimal outcome'
| * rather than a 'failing outcome'.
| * <p/>
| * An example of when this method is useful is when data is read from, for example, a legacy datastore, and is cached before
| * returning the data to the caller. Subsequent calls would prefer to get the data from the cache and if the data doesn't exist
| * in the cache, fetch again from the legacy datastore.
| * <p/>
| * See <a href="http://jira.jboss.com/jira/browse/JBCACHE-848">JBCACHE-848</a> for details around this feature.
| * <p/>
| *
| * @param fqn <b><i>absolute</i></b> {@link Fqn} to the {@link Node} to be accessed.
| * @param key key with which the specified value is to be associated.
| * @param value value to be associated with the specified key.
| * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.jboss.cache.CacheStatus#STARTED}.
| */
| void putForExternalRead(Fqn fqn, K key, V value);
|
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4268556#4268556
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4268556
16 years, 4 months
[JBoss Cache Users] - Re: How to prevent TimeoutException?
by galder.zamarreno@jboss.com
As indicated in the documentation, JBoss Cache uses lock stripping by default and you can control the shared pool of locks by tweaking the concurrency level, as you already did. However, lock striping, under certain circumstances, can lead to deadlocks as indicated in https://jira.jboss.org/jira/browse/JBCACHE-1494. So, something good to try is to run your benchmark with:
<locking .... useLockStriping="false" />
More generally, debugging TimeoutExceptions involves generally producing some thread dumps when these are reported. The idea here is finding out which other thread might be holding that particular lock and see whether it's hanged or waiting for something else and see if that other resource can be tweaked accordingly.
Tools like JVisualVM (part of the jdk) can both generate and analyse thread dumps, otherwise you can use the rudimentary kill -3 or equivalent method and use standalone tools like to inspect them, i.e.:
- TDA (https://tda.dev.java.net/)
- or Samurai (http://yusuke.homeip.net/samurai/en/index.html)
Other tips to get around TimeoutExceptions include reducing the transactional scope of the operation that is holding the lock. That way, the time the lock is held is reduced and hence it's released earlier. Reducing the transactional scope can be achieved by either moving some operations out of the transaction or finding more efficient ways to do what is being done within the transaction.
Sometimes these TimeoutException can hide behind memory issues that produce long garbage collection periods. Turning on garbage collection logging (http://www.jboss.org/community/docs/DOC-12451) can help visualise whether there are noticeable stoppages. Turning on VM parameters can sometimes help reduce the stoppages which in turn increases speed of operation and consequently reduces TimeoutException occurrences.
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4268551#4268551
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4268551
16 years, 4 months
[jBPM Users] - Re: Variables keep old values
by aroeder
I wrote a JUnit test for showing my problem:
| package de.firstdata.test;
|
| import java.io.IOException;
| import java.util.HashMap;
| import java.util.Map;
| import java.util.Set;
|
| import org.jbpm.graph.def.ProcessDefinition;
| import org.jbpm.graph.exe.ProcessInstance;
| import org.jbpm.taskmgmt.exe.TaskInstance;
|
| import de.firstdata.config.TicketServiceConfigService;
| import de.firstdata.dm.JBPMContextWrapper;
| import de.firstdata.dm.TicketSystemDomainModelFacade;
|
| public class JbpmVariablesTest extends ATicketServiceTestA {
|
| private TicketSystemDomainModelFacade facade = null;
|
| @SuppressWarnings("unchecked")
| public void testVariables() throws IOException {
|
| JBPMContextWrapper ctx = getContextWrapper();
|
| try {
| ProcessDefinition processDefinition = ProcessDefinition
| .parseXmlString("<process-definition xmlns='' name='ABR'>" + "<start-state name='start-state1'>"
| + "<transition to='edit'></transition>" + "</start-state>" + "<task-node name='edit'>"
| + "<task name='edit'>" + " <controller>"
| + " <variable access='read,write,required' name='inbox'></variable>" + " </controller>"
| + "</task>" + "<transition to='change' name='tochange'></transition>"
| + "<transition to='end-state1' name='done'></transition>" + "</task-node>"
| + "<task-node name='change'>" + "<task name='indexDataChange'>" + " <controller>"
| + " <variable access='read,write,required' name='inbox'></variable>" + " </controller>"
| + "</task>" + "<transition to='edit' name='back'></transition>" + "</task-node>"
| + "<end-state name='end-state1'></end-state>" + "</process-definition>");
|
| Map<String, String> myMap = new HashMap<String, String>();
| myMap.put("inbox", "COMPLAINTS_MANAGEMENT");
|
| ctx.deployProcessDefinition(processDefinition);
| ProcessInstance processInstance = processDefinition.createProcessInstance(myMap);
| ctx.save(processInstance);
| processInstance.signal();
|
| TaskInstance taskEdit = getTaskInstance(processInstance, "edit");
| taskEdit.end("tochange");
|
| ctx.save(taskEdit);
|
| TaskInstance taskChange = getTaskInstance(processInstance, "indexDataChange");
| Map<String, String> variables = taskChange.getContextInstance().getVariables();
| variables.put("inbox", "CS_ISO");
| taskChange.getProcessInstance().getContextInstance().addVariables(variables);
| ctx.save(taskChange);
| ctx.close();
| ctx = getContextWrapper();
|
| taskChange.end("back");
|
| taskEdit = getTaskInstance(processInstance, "edit");
| Map<String, String> changedVariables = taskEdit.getProcessInstance().getContextInstance().getVariables();
|
| String inbox = (String) changedVariables.get("inbox");
|
| taskEdit.end("done");
| processInstance.end();
| ctx.deleteProcessDefinition(processDefinition);
|
| assertEquals("CS_ISO", inbox);
| } finally {
| ctx.close();
| }
| }
|
| private JBPMContextWrapper getContextWrapper() {
| if (facade == null) {
| facade = (TicketSystemDomainModelFacade) TicketServiceConfigService.getConfig().getFacade();
| }
| return JBPMContextWrapper.getInstance("jbpm.cfg.xml", facade);
| }
|
| @SuppressWarnings("unchecked")
| private TaskInstance getTaskInstance(final ProcessInstance processInstance, final String taskInstanceName) {
| TaskInstance returnInstance = null;
| Set<TaskInstance> tasks = (Set<TaskInstance>) processInstance.getTaskMgmtInstance().getTaskInstances();
|
| for (TaskInstance ti : tasks) {
| if (ti.getName().equals(taskInstanceName) && !ti.hasEnded()) {
| returnInstance = ti;
| }
| }
|
| return returnInstance;
| }
| }
|
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4268545#4268545
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4268545
16 years, 4 months