Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Bitronix Transaction Manager
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<h1>BTM Implementation details</h1><p>BTM is made of multiple modules which map as close as possible the JTA API.</p><p>This page contains descriptions of those components and how they work internally in BTM 1.3 and 2.x.x as version 1.2 and earlier did not fully respect this modularization.</p><h4>Contents</h4><p><img class="editor-inline-macro" src="/plugins/servlet/confluence/placeholder/macro?definition=e3RvYzptYXhMZXZlbD0zfG1pbkxldmVsPTJ9&locale=en_GB&version=2" data-macro-name="toc" data-macro-parameters="maxLevel=3|minLevel=2"></p><h2>Bitronix implementation specifics</h2><h3>XID</h3><p>The JTA specification defines XID as an interface for which an implementation must be provided by the transaction manager. There are 3 important pieces composing a XID: the format ID, the Global TRansaction ID (GTRID) and the Branch QUALifier (BQUAL).</p><h4>Format ID</h4><p>The format ID identifies the transaction manager which generated the XID. It basically is an integer which must be unique across all implementations. The BTM format ID simply is the int-encoded version of the "Btnx" ASCII string: 0x42746e78.</p><h4>GTRID</h4><p>The GTRID uniquely identifies the global transaction across all participating resources. The JTA spec says it must fit in a 64 bytes array and must be globally unique. The BTM implementation builds them by combining 3 data: the serverId, a timestamp and a sequence number.</p><h4>BQUAL</h4><p>The BQUAL uniquely identifies the local part of a global transaction inside a single participating resource. As for the GTRID the JTA spec says it must fit in a 64 bytes array and must be globally unique. The BTM BQUALs are built with the exact same format as the GTRID.</p><p><img class="confluence-embedded-image" src="/download/attachments/231080169/xid.gif?version=1&modificationDate=1369424734716" data-image-src="/download/attachments/231080169/xid.gif?version=1&modificationDate=1369424734716" data-linked-resource-id="231375772" data-linked-resource-type="attachment" data-linked-resource-default-alias="xid.gif" data-base-url="http://docs.codehaus.org" data-linked-resource-container-id="231080169" title="null > xid.gif"></p><ul><li>The <strong>serverId</strong> is the configured ASCII string, see <a class="confluence-link" href="/display/BTM/Configuration2x#Configuration2x-Transactionenginesettings" data-anchor="Transactionenginesettings" data-linked-resource-id="183074829" data-linked-resource-type="page" data-linked-resource-default-alias="Configuration2x#Transactionenginesettings" data-base-url="http://docs.codehaus.org">Configuration2x#Transactionenginesettings</a>.</li><li>The <strong>timestamp</strong> is the amount of milliseconds returned by calls to <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis%28%29">http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis%28%29</a></li><li>The <strong>sequence</strong> is a static counter that each JVM maintains independently. It is re-initialized to 0 each time the JVM running a BTM instance is restarted.</li></ul><h2>2PC engine</h2><p>todo.</p><h3>asynchronous2Pc</h3><p>Async 2PC is a very complex optimization that isn't useful in most cases. The idea is to run the 2PC protocol in parallel (ie: sending the phase 1 then phase 2 commands in parallel to all participating resources). In theory this should give you a big performance boost but in practice it's negligible except if you have lots of participating resources. Performance improvement has been measured on average only when at least 4 resources are participating in transactions.</p><p>It is not recommended to enable this setting unless you measured your average 2PC execution time and identified a bottleneck.</p><h2>XA connection pooling framework</h2><p>XA transactions require connection pools with specific knowledge of transactions' state. For instance it is not possible to use a non-XA connection pool like C3P0 or Apache DBCP with the transaction manager.</p><p>An abstract XA connection pool lies at the heart of BTM with JDBC and JMS layers on top of it. Everything which can be pooled or cached actually is: JDBC and JMS connections are pooled, JDBC prepared statements can be cached as well as JMS sessions, producers and consumers.</p><p>Extra services and optimizations are also provided like automatic enlisting and delisting, deferral of connection closing, ordering of resources in the 2PC protocol, connection recycling, non-XA safeguard and Last Resource Commit.</p><h3>allowLocalTransactions</h3><p>todo.</p><h3>twoPcOrderingPosition</h3><p>todo.</p><h3>deferConnectionRelease</h3><p>todo.</p><h2>Disk journal</h2><p>The disk journal is a simple two-files (called <em>fragments</em>) rollover transaction store, this sometimes is called <em>append only</em> journal or <em>write ahead log</em>. It provides services to the transaction manager engine to record transaction states and reporting of transactions left in an unfinished state: transactions which reached the end of the 1st phase of the 2PC protocol (<em>prepare</em>) but suffered from a failure before the 2nd phase (<em>commit or rollback</em>) could finish up.</p><p>The disk journal implements all known optimizations:</p><ul><li>pre-allocated storage of variable size</li><li>journal compacting</li><li>disk force (or disk sync) batching with a flip-flop algorithm</li></ul><h2>Recovery engine</h2><p>todo.</p><h3>currentNodeOnlyRecovery</h3><p>This setting is very important when you're running a cluster of virtual machines all working on the same resource. In this case BTM will run multiple times in parallel, each node creating different transactions on the resource. Since the XIDs are guaranteed to be globally unique this isn't a problem for the transaction manager core.</p><p>The recovery engine can on the other hand get confused with this setup. Take for instance this scenario:</p><p><img class="confluence-embedded-image" src="/download/attachments/231080169/currentNodeOnlyRecovery.gif?version=1&modificationDate=1369424734692" data-image-src="/download/attachments/231080169/currentNodeOnlyRecovery.gif?version=1&modificationDate=1369424734692" data-linked-resource-id="231375771" data-linked-resource-type="attachment" data-linked-resource-default-alias="currentNodeOnlyRecovery.gif" data-base-url="http://docs.codehaus.org" data-linked-resource-container-id="231080169" title="null > currentNodeOnlyRecovery.gif"></p><p>Two servers are accessing a single database. Server 1 started a transaction identified by XID 1 while at the same time server 2 started a transaction identified by XID 2. Now what would happen if recovery kicks in in the background on server 1 (or if server 1 gets restarted) while XID 2 is still in-flight on server 2? Server 1 would ask its journal for a list of unfinished transactions and compare that against the list of XIDs it got by querying the database. We can ignore XID 1 in this case as the TM has knowledge of it and we can assume it would handle it fine. But what is server 1 supposed to do with XID 2? It is reported by the database as an unfinished transaction and server 1 has no trace of it in its journal. As per the <em>presumed abort</em> optimization the recovery engine will assume that the transaction needs to be rolled back as it has no knowledge that it still is running on server 2!</p><p>To avoid this confusion, the recovery engine can be configured to peek at the XID to determine if it actually started it before taking any action. It can do that by extracting the <code>serverId</code> part of the XID stored in the database and comparing it to the current node's configured <code>serverId</code>. If they don't match then the XID can be ignored assuming another node is taking/will take care of it.</p><p>This is what the <code>currentNodeOnlyRecovery</code> setting is about: it tells the recovery engine to ignore XIDs started by another node.</p><p><img class="confluence-embedded-image confluence-external-resource" src="http://www.bitronix.be/images/shim.gif" data-image-src="http://www.bitronix.be/images/shim.gif"></p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced