Return-Path: X-Original-To: apmail-geronimo-scm-archive@www.apache.org Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E777DDC02 for ; Tue, 24 Jul 2012 12:55:35 +0000 (UTC) Received: (qmail 84557 invoked by uid 500); 24 Jul 2012 12:55:35 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 84370 invoked by uid 500); 24 Jul 2012 12:55:31 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 84339 invoked by uid 99); 24 Jul 2012 12:55:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Jul 2012 12:55:31 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Jul 2012 12:55:29 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 0704F238897F; Tue, 24 Jul 2012 12:54:46 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1365021 - in /geronimo/components/txmanager/trunk/geronimo-transaction/src: main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java Date: Tue, 24 Jul 2012 12:54:45 -0000 To: scm@geronimo.apache.org From: gnodet@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120724125446.0704F238897F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: gnodet Date: Tue Jul 24 12:54:45 2012 New Revision: 1365021 URL: http://svn.apache.org/viewvc?rev=1365021&view=rev Log: GERONIMO-6372: RecoveryImpl completing in-progress transactions, XidFactoryImpl needs to be smarter with matching Added: geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java?rev=1365021&r1=1365020&r2=1365021&view=diff ============================================================================== --- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java (original) +++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/XidFactoryImpl.java Tue Jul 24 12:54:45 2012 @@ -17,10 +17,10 @@ package org.apache.geronimo.transaction.manager; -import java.util.Random; -import javax.transaction.xa.Xid; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Random; +import javax.transaction.xa.Xid; /** * Factory for transaction ids. @@ -35,10 +35,11 @@ import java.net.UnknownHostException; */ public class XidFactoryImpl implements XidFactory { private final byte[] baseId = new byte[Xid.MAXGTRIDSIZE]; - private long count = 1; + private final long start = System.currentTimeMillis(); + private long count = start; public XidFactoryImpl(byte[] tmId) { - System.arraycopy(tmId, 0, baseId, 8, tmId.length); + System.arraycopy(tmId, 0, baseId, 8, tmId.length); } public XidFactoryImpl() { @@ -68,14 +69,7 @@ public class XidFactoryImpl implements X synchronized (this) { id = count++; } - globalId[0] = (byte) id; - globalId[1] = (byte) (id >>> 8); - globalId[2] = (byte) (id >>> 16); - globalId[3] = (byte) (id >>> 24); - globalId[4] = (byte) (id >>> 32); - globalId[5] = (byte) (id >>> 40); - globalId[6] = (byte) (id >>> 48); - globalId[7] = (byte) (id >>> 56); + insertLong(id, globalId, 0); return new XidImpl(globalId); } @@ -85,6 +79,7 @@ public class XidFactoryImpl implements X branchId[1] = (byte) (branch >>> 8); branchId[2] = (byte) (branch >>> 16); branchId[3] = (byte) (branch >>> 24); + insertLong(start, branchId, 4); return new XidImpl(globalId, branchId); } @@ -97,14 +92,22 @@ public class XidFactoryImpl implements X return false; } } - return true; + // for recovery, only match old transactions + long id = extractLong(globalTransactionId, 0); + return (id < start); } public boolean matchesBranchId(byte[] branchQualifier) { if (branchQualifier.length != Xid.MAXBQUALSIZE) { return false; } - for (int i = 8; i < branchQualifier.length; i++) { + long id = extractLong(branchQualifier, 4); + if (id >= start) { + // newly created branch, not recoverable + return false; + } + + for (int i = 12; i < branchQualifier.length; i++) { if (branchQualifier[i] != baseId[i]) { return false; } @@ -116,4 +119,26 @@ public class XidFactoryImpl implements X return new XidImpl(formatId, globalTransactionid, branchQualifier); } + static void insertLong(long value, byte[] bytes, int offset) { + bytes[offset + 0] = (byte) value; + bytes[offset + 1] = (byte) (value >>> 8); + bytes[offset + 2] = (byte) (value >>> 16); + bytes[offset + 3] = (byte) (value >>> 24); + bytes[offset + 4] = (byte) (value >>> 32); + bytes[offset + 5] = (byte) (value >>> 40); + bytes[offset + 6] = (byte) (value >>> 48); + bytes[offset + 7] = (byte) (value >>> 56); + } + + static long extractLong(byte[] bytes, int offset) { + return (bytes[offset + 0] & 0xff) + + (((bytes[offset + 1] & 0xff)) << 8) + + (((bytes[offset + 2] & 0xff)) << 16) + + (((bytes[offset + 3] & 0xffL)) << 24) + + (((bytes[offset + 4] & 0xffL)) << 32) + + (((bytes[offset + 5] & 0xffL)) << 40) + + (((bytes[offset + 6] & 0xffL)) << 48) + + (((long) bytes[offset + 7]) << 56); + } + } Added: geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java?rev=1365021&view=auto ============================================================================== --- geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java (added) +++ geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/XidFactoryImplTest.java Tue Jul 24 12:54:45 2012 @@ -0,0 +1,64 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.geronimo.transaction.manager; + +import java.util.concurrent.TimeUnit; +import javax.transaction.xa.Xid; + +import junit.framework.TestCase; + +public class XidFactoryImplTest extends TestCase { + + public void testLong() { + byte[] buffer = new byte[64]; + long l1 = 1343120074022l; + XidFactoryImpl.insertLong(l1, buffer, 4); + long l2 = XidFactoryImpl.extractLong(buffer, 4); + assertEquals(l1, l2); + + l1 = 1343120074022l - TimeUnit.DAYS.toMillis(15); + XidFactoryImpl.insertLong(l1, buffer, 4); + l2 = XidFactoryImpl.extractLong(buffer, 4); + assertEquals(l1, l2); + } + + public void testFactory() throws Exception { + XidFactory factory = new XidFactoryImpl("hi".getBytes()); + Xid id1 = factory.createXid(); + Xid id2 = factory.createXid(); + + assertFalse("Should not match new: " + id1, factory.matchesGlobalId(id1.getGlobalTransactionId())); + assertFalse("Should not match new: " + id2, factory.matchesGlobalId(id2.getGlobalTransactionId())); + + Xid b_id1 = factory.createBranch(id1, 1); + Xid b_id2 = factory.createBranch(id2, 1); + + assertFalse("Should not match new branch: " + b_id1, factory.matchesBranchId(b_id1.getBranchQualifier())); + assertFalse("Should not match new branch: " + b_id2, factory.matchesBranchId(b_id2.getBranchQualifier())); + + Thread.sleep(5); + + XidFactory factory2 = new XidFactoryImpl("hi".getBytes()); + assertTrue("Should match old: " + id1, factory2.matchesGlobalId(id1.getGlobalTransactionId())); + assertTrue("Should match old: " + id2, factory2.matchesGlobalId(id2.getGlobalTransactionId())); + + assertTrue("Should match old branch: " + b_id1, factory2.matchesBranchId(b_id1.getBranchQualifier())); + assertTrue("Should match old branch: " + b_id2, factory2.matchesBranchId(b_id2.getBranchQualifier())); + } + +}