Author: kwall
Date: Fri Dec 14 14:25:09 2012
New Revision: 1421884
URL: http://svn.apache.org/viewvc?rev=1421884&view=rev
Log:
QPID-4503: Producer transaction timeout detection feature may produce suprious
open/idle alerts and close client connections/sessions without good cause
Race conditon existed between the initial check that determined transaction
timeout detection was required and the subsequent re-observeration
required to perform the open and idle calculation. In the unlucky timing, the
state of the transaction changed between these two points. (To produce
the time-since-epoch type the transaction needs to be committed between these
two points).
Changed checkTransactionStatus so that transactionStartTime and
transactionUpdateTime are observed once only.
There still exists the possibility that the transaction status change change
between the reading of transactionStartTime and transactionUpdateTime
times, but I do not see how this could produce a suprious report (or close).
The alternative (to take a locks to ensure consistent observations
are made) seems unjustifiably costly.
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java?rev=1421884&r1=1421883&r2=1421884&view=diff
==============================================================================
---
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
(original)
+++
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
Fri Dec 14 14:25:09 2012
@@ -70,7 +70,6 @@ import org.apache.qpid.server.message.Me
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.protocol.AMQProtocolEngine;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
@@ -113,7 +112,7 @@ public class AMQChannel implements AMQSe
*/
private long _deliveryTag = 0;
- /** A channel has a default queue (the last declared) that is used when no
queue name is explictily set */
+ /** A channel has a default queue (the last declared) that is used when no
queue name is explicitly set */
private AMQQueue _defaultQueue;
/** This tag is unique per subscription to a queue. The server returns
this in response to a basic.consume request. */
@@ -209,10 +208,6 @@ public class AMQChannel implements AMQSe
}
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 &&
_transaction.getTransactionStartTime() > 0;
- }
private void incrementOutstandingTxnsIfNecessary()
{
@@ -1487,11 +1482,13 @@ public class AMQChannel implements AMQSe
public void checkTransactionStatus(long openWarn, long openClose, long
idleWarn, long idleClose) throws AMQException
{
- if (inTransaction())
+ final long transactionStartTime =
_transaction.getTransactionStartTime();
+ final long transactionUpdateTime = _txnUpdateTime.get();
+ if (isTransactional() && transactionUpdateTime > 0 &&
transactionStartTime > 0)
{
long currentTime = System.currentTimeMillis();
- long openTime = currentTime -
_transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
+ long openTime = currentTime - transactionStartTime;
+ long idleTime = currentTime - transactionUpdateTime;
_transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn,
ChannelMessages.IDLE_TXN(idleTime),
TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT);
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java?rev=1421884&r1=1421883&r2=1421884&view=diff
==============================================================================
---
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
(original)
+++
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
Fri Dec 14 14:25:09 2012
@@ -42,7 +42,6 @@ import javax.security.auth.Subject;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.TransactionTimeoutHelper;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
@@ -449,11 +448,6 @@ public class ServerSession extends Sessi
return _transaction.isTransactional();
}
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 &&
_transaction.getTransactionStartTime() > 0;
- }
-
public void selectTx()
{
_transaction = new LocalTransaction(this.getMessageStore());
@@ -591,7 +585,7 @@ public class ServerSession extends Sessi
/**
* Update last transaction activity timestamp
*/
- public void updateTransactionalActivity()
+ private void updateTransactionalActivity()
{
if (isTransactional())
{
@@ -709,11 +703,13 @@ public class ServerSession extends Sessi
public void checkTransactionStatus(long openWarn, long openClose, long
idleWarn, long idleClose) throws AMQException
{
- if (inTransaction())
+ final long transactionStartTime =
_transaction.getTransactionStartTime();
+ final long transactionUpdateTime = _txnUpdateTime.get();
+ if (isTransactional() && transactionUpdateTime > 0 &&
transactionStartTime > 0)
{
long currentTime = System.currentTimeMillis();
- long openTime = currentTime -
_transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
+ long openTime = currentTime - transactionStartTime;
+ long idleTime = currentTime - transactionUpdateTime;
_transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn,
ChannelMessages.IDLE_TXN(idleTime),
TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT);
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java?rev=1421884&r1=1421883&r2=1421884&view=diff
==============================================================================
---
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
(original)
+++
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
Fri Dec 14 14:25:09 2012
@@ -50,7 +50,7 @@ public class LocalTransaction implements
private volatile Transaction _transaction;
private MessageStore _transactionLog;
- private long _txnStartTime = 0L;
+ private volatile long _txnStartTime = 0L;
private StoreFuture _asyncTran;
public LocalTransaction(MessageStore transactionLog)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]