[JBossCache] - Re: Problem with transaction timeout [critical]
by jacek187
Small cosmetic test fix:
AsyncRollbackTransactionManager
| package org.jboss.cache.transaction;
|
| import java.util.HashMap;
| import java.util.Iterator;
| import java.util.Map;
| import java.util.Properties;
|
| import javax.naming.Context;
| import javax.naming.InitialContext;
| import javax.naming.NamingException;
| import javax.transaction.HeuristicMixedException;
| import javax.transaction.HeuristicRollbackException;
| import javax.transaction.InvalidTransactionException;
| import javax.transaction.NotSupportedException;
| import javax.transaction.RollbackException;
| import javax.transaction.SystemException;
| import javax.transaction.Transaction;
|
| public class AsyncRollbackTransactionManager extends DummyTransactionManager{
| static AsyncRollbackTransactionManager instance=null;
|
| public static DummyTransactionManager getInstance() {
| if(instance == null) {
| instance=new AsyncRollbackTransactionManager();
| try {
| Properties p=new Properties();
| p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
| Context ctx=new InitialContext(p);
| ctx.bind("java:/TransactionManager", instance);
| ctx.bind("UserTransaction", new DummyUserTransaction(instance));
| }
| catch(NamingException e) {
| log.error("binding of DummyTransactionManager failed", e);
| }
| }
| return instance;
| }
|
| private Thread timedOutTransactionsChecker = null;
| private int timeout = 30;
| private Map txMap = new HashMap();
| @Override
| public void setTransactionTimeout(int seconds) throws SystemException {
| this.timeout = seconds;
| }
| public AsyncRollbackTransactionManager(){
| timedOutTransactionsChecker = new TimedOutTransactionsChecker();
| timedOutTransactionsChecker.start();
| }
| private class TimedOutTransactionsChecker extends Thread{
| private boolean running;
| public TimedOutTransactionsChecker(){
| }
| public void run() {
| running = true;
| while (running){
| try {
| Thread.sleep(500);
| synchronized(this)
| {
| Iterator iterator = txMap.values().iterator();
| do
| {
| if(!iterator.hasNext())
| break;
| AsyncRollbackTransaction t = (AsyncRollbackTransaction)iterator.next();
| try {
| t.wakeUp();
| } catch (SystemException e) {
| e.printStackTrace();
| }
|
| } while(true);
| }
| } catch (InterruptedException e) {
| }
| }
| }
|
| }
| @SuppressWarnings("unchecked")
| @Override
| public void begin() throws NotSupportedException, SystemException {
| Transaction currentTx;
| if((currentTx=getTransaction()) != null)
| throw new NotSupportedException(Thread.currentThread() +
| " is already associated with a transaction (" + currentTx + ")");
| AsyncRollbackTransaction tx=new AsyncRollbackTransaction(this,timeout);
| setTransaction(tx);
| txMap.put(tx.generateTransactionId(), tx);
| }
| @Override
| public void rollback() throws IllegalStateException, SecurityException, SystemException {
| removeTxFromMap((AsyncRollbackTransaction) getTransaction());
| super.rollback();
| }
| public void removeTxFromMap(AsyncRollbackTransaction tx) throws SystemException {
| if (tx!=null){
| txMap.remove(tx.getTransactionId());
| }
| }
| @Override
| public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException {
| AsyncRollbackTransaction tx=(AsyncRollbackTransaction) getTransaction();
| if (tx!=null){
| txMap.remove(tx.getTransactionId());
| }
| super.commit();
| }
| @Override
| public void resume(Transaction tx) throws InvalidTransactionException, IllegalStateException, SystemException {
| //TODO Not implemented TX timeout counting
| super.resume(tx);
| }
| @Override
| public Transaction suspend() throws SystemException {
| //TODO Not implemented TX timeout counting
| return super.suspend();
| }
| }
|
AsyncRollbackTransaction
| package org.jboss.cache.transaction;
|
| import javax.transaction.SystemException;
|
|
| public class AsyncRollbackTransaction extends DummyTransaction {
| private static long transactionNums = 0;
|
| private long transactionId;
|
| private long beginTimeMillis;
|
| private int timeoutSec;
|
| public AsyncRollbackTransaction(DummyBaseTransactionManager tm, int timeout) {
| super(tm);
| this.timeoutSec = timeout;
| this.beginTimeMillis = System.currentTimeMillis();
| }
|
| /**
| * @return the transactionId
| */
| public long getTransactionId() {
| return transactionId;
| }
|
| public long generateTransactionId() {
| long result = 0;
| synchronized (AsyncRollbackTransaction.class) {
| transactionNums++;
| result = transactionNums;
| }
| this.transactionId = result;
| return result;
| }
|
| final int getTimeoutSeconds() {
| return timeoutSec;
| }
|
| protected final void asyncRollback() throws SystemException {
| Thread asyncRollbackThread = new Thread() {
| public void run() {
| try {
| rollback();
| } catch (Exception exception) {
| }
| }
| };
| ((AsyncRollbackTransactionManager)tm_).removeTxFromMap(this);
| asyncRollbackThread.start();
| }
|
| public void wakeUp() throws SystemException {
| if (isTransactionTimedOut()) {
| asyncRollback();
| }
| }
| private boolean isTransactionTimedOut() {
| return (System.currentTimeMillis() - beginTimeMillis) > (timeoutSec * 1000);
| }
| }
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3998500#3998500
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3998500
19 years, 3 months
[JBoss Seam] - Re: Refreshing dataTable - Too many conversation
by FabBoco
After some experiments I realized that:
1) If I start the Test page from the browser with localhost:8080/application/Test.seam and I refresh the page a new conversation is started. This is true if and only if I have a call to the TestBeam (ex <h:outputText value="#{TestManager.property}"></h:outputText> or the dataTable)
If I have not a call to the TestBean the conversation is not even started.
Let me say that if I start the Test page directly from the browser the page itself is 'detached' from the conversation, or in other words, the page can starts a conversation but it is not able to be attached to it.
2) If I start the Test page from a different page (StartTest, which does not start any conversation) and I start the TestPage calling the startPage method, I am able to refresh the page as much I like without new conversation starts. This is true even if I have <page view-id="/Test.jsp" action="#{TestManager.onListLoad}" /> in the pages.xml. Obviously the table is refreshed (it was my original problem !!).
Let me say that in this case the Test page is 'attached' to its conversation. There is a clue of the 'attachement': the URL in the browser is: localhost:8080/application/Test.seam?conversationId=number
3) Removing @Begin(join=true) from the findAll method no conversation at all is started (!!! ???)
4) The behaviour is the same if I put the bean either into the SESSION or into the CONVERSATION
Now, question is: How can I make the Test page knows that it is attached to a conversation (or better that I will be attached to a conversation) when I start it directly from the browser ?
Comments and help are welcome.
Fabrizio
Test page
| <f:view>
| <f:loadBundle basename="messages" var="msgs" />
| <h:form>
| <br>
| <t:dataTable id="cd" var="cd" preserveDataModel="false" value="#{cdList}" width="100%" ....>
|
| <h:column>
| <f:facet name="header">
| <h:outputText value="titolo" />
| </f:facet>
| <h:outputText value="#{cd.titolo}" />
| </h:column>
| </t:dataTable>
|
| <br>
| <hr>
| <h:outputText value="#{TestManager.property}"></h:outputText>
| <hr>
| <br>
| <h:commandLink action="#{TestManager.onListLoad}" value="Reload">
| </h:commandLink>
|
| </h:form>
| </f:view>
|
StartTest page
| <f:view>
| <f:loadBundle basename="messages" var="msgs" />
| <h:form>
| <h1>Start Page</h1>
| <hr>
| <br>
| <h:commandButton action="#{TestManager.startPage}" value="Start Page" />
| </h:form>
| </f:view>
|
Bean
| @Stateful
| @Name("TestManager")
| @Scope(ScopeType.SESSION)
| @Transactional
| public class TestManagerBean implements Serializable, TestManager
| {
| @PersistenceContext(type = PersistenceContextType.EXTENDED)
| private EntityManager em;
| private String property= "DISPLAY";
|
| @DataModel(value = "cdList")
| private List<Cd> cdList;
| public TestManagerBean()
| {
| }
|
| @Create
| public void create()
| {
| }
|
| @Factory("cdList")
| @Begin(join=true)
| public void findAll()
| {
| Query q = em.createQuery("select o from Cd o");
| cdList = q.getResultList();
| }
|
| @Remove
| @Destroy
| public void destroy()
| {
| }
|
| public void setProperty(String operation)
| {
| this.property = operation;
| }
|
| public String getProperty()
| {
| return property;
| }
|
| public void onListLoad()
| {
| cdList = null;
| System.out.println("reload");
| }
|
| public String startPage()
| {
| return "/Test.jsp";
| }
| }
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3998497#3998497
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3998497
19 years, 3 months