<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ScappShots</title>
	<atom:link href="http://blog.scapps.co.uk/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.scapps.co.uk</link>
	<description>Dan Stone on scalable application strategies</description>
	<lastBuildDate>Sun, 25 Mar 2012 22:15:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>NCache Concurrency Controls</title>
		<link>http://blog.scapps.co.uk/?p=214</link>
		<comments>http://blog.scapps.co.uk/?p=214#comments</comments>
		<pubDate>Thu, 08 Mar 2012 18:50:31 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[NCache]]></category>
		<category><![CDATA[What I'm Working On]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[locking]]></category>
		<category><![CDATA[nCache]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=214</guid>
		<description><![CDATA[Recently I have been looking into .NET-friendly in-memory data grid (IMDG) software. One of the products I have been experimenting with is Alachisoft&#8217;s NCache. When I analyze a distributed caching product, I like to focus first on concurrency control. Before examining performance, scalability, or advanced architectural features, it is valuable to confirm that the software [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have been looking into .NET-friendly in-memory data grid (IMDG) software. One of the products I have been experimenting with is Alachisoft&#8217;s NCache.</p>
<p>When I analyze a distributed caching product, I like to focus first on concurrency control. Before examining performance, scalability, or advanced architectural features, it is valuable to confirm that the software can be used to construct applications that remain reliable when data is shared and subject to updates. To do this I usually construct a test case involving extreme data hot spots, and exercise the features offered by the product for managing data access in these heavy contention situations.</p>
<p>If the product I&#8217;m working with offers features for dividing work into ACID style transactions then I explore those features as part of my analysis of concurrent data access. NCache does not provide features for using ACID transactions, so my work with NCache has focused on its locking features.</p>
<p>NCache provides both optimistic and pessimistic concurrency control. The pessimistic locking model turns out to be unusual, at least in my experience. Although the documentation on this feature is quite sparse, with help from the (very responsive) tech. support team at Alachisoft I was able to get an understanding of how NCache&#8217;s pessimistic locking works and how to use the NCache API to control it.</p>
<p>Here are some key points about NCache&#8217;s pessimistic locking:</p>
<p>1. The NCache data access API provides specialized methods for acquiring locks, releasing locks and accessing items in the cache under locking constraints.</p>
<p>2. Each lock represents the state of an item of data in the cache.</p>
<p>3. Locks are not granted to a thread or a process. Every lock is equally visible to and manipulable by all cache client threads, regardless of which thread originally requested the lock.</p>
<p>4. Locking is completely cooperative. If locking is used to control access to a data item then, to ensure that exclusive access to that item will be maintained until the routine that requested the lock relinquishes it, every potentially concurrent access to that item must be made using the locking form of the NCache data access API. Using a non-locking API method to access a locked item will bypass the lock.</p>
<p>5. In at least one case, using a non-locking API method will not only bypass the lock but will remove it.</p>
<p>6. NCache&#8217;s locks will never cause a client thread to block. Data access methods that access a locked item in the cache will return right away. Clients must include logic to interpret the results of the method invocation and retry it if appropriate.</p>
<p>7. In some cases, to determine why a method has not been successful the side effects of the method must be examined.</p>
<p>This final point requires a fuller explanation. Most of the the pessimistic locking API methods take a reference to an object called a LockHandle as one of their arguments. A LockHandle stores the information that identifies a lock on a data item. The values stored in the LockHandle you pass in may be changed by the method. Depending on which method you use and the state (locked or unlocked) of the item you are trying to access, to interpret the results of your locking call it may be necessary to inspect the values in the LockHandle you passed in. Here is an example:</p>
<p>The Get() method takes a key and returns the associated cached item if there is one. The locking form of the Get() method takes three additional arguments, one of which is a LockHandle reference. Depending on the values of those arguments, the method can be used to lock an object and retrieve it in a single call. In this case the method will return null if there is no object in the cache with the specified key value, or if the object exists but is already locked. To distinguish between these two cases the caller must examine the post-call values in the LockHandle.</p>
<p>NCache&#8217;s concurrency features work as intended, and with them I was able to maintain the data consistency required by my test scenario. Both the optimistic and the pessimistic features delivered correct results when data items were subject to vigorous concurrent access. However, when compared with the concurrency features provided by well known competitors, NCache&#8217;s concurrency controls are quirky and not particularly developer-friendly. Its vulnerability to pessimistic locks being accidentally bypassed or removed by clients that don&#8217;t conform to the cooperative lock management protocol makes applications that depend on exclusive data access prone to bugs. The non-blocking approach may be welcome in some situations, but the lack of blocking calls is likely to lead to increased client code complexity and reduced performance in many cases. The lack of support for ACID transactions poses a significant obstacle to building applications that must maintain strict data consistency. For some use cases NCache&#8217;s pessimistic locking or its optimistic concurrency features may suffice, but developers designing a system with shared access to writable data should study its concurrency control feature set carefully before choosing NCache.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=214</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Support in GigaSpaces XAP</title>
		<link>http://blog.scapps.co.uk/?p=199</link>
		<comments>http://blog.scapps.co.uk/?p=199#comments</comments>
		<pubDate>Fri, 24 Feb 2012 09:43:55 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[GigaSpaces]]></category>
		<category><![CDATA[What I'm Working On]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[caching]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=199</guid>
		<description><![CDATA[Introduction (download PDF version with illustrations) Some work I did for a client a few months ago started me thinking about distributed caching options for .NET. Among the well known distributed caching products, only NCache was designed specifically for .NET, with Microsoft’s own Velocity project expected to mature into a viable product shortly.  Others such [...]]]></description>
			<content:encoded><![CDATA[<h3 style="text-align: left;" align="center">Introduction</h3>
<p>(<a title="Download PDF" href="http://tinyurl.com/74mynmd">download PDF version with illustrations</a>)</p>
<p>Some work I did for a client a few months ago started me thinking about distributed caching options for .NET. Among the well known distributed caching products, only NCache was designed specifically for .NET, with Microsoft’s own Velocity project expected to mature into a viable product shortly.  Others such as Oracle Coherence, Terracotta with EHCache , VMWare GemFire and  GigaSpaces XAP are based on non-.NET (primarily Java) ecosystems, but most of them provide some level of support for .NET applications.  This post provides a simple framework for comparing the .NET support provided by these products and a summary of what I found when I began exploring GigaSpaces’ XAP .NET edition.</p>
<p>Framework for Comparison</p>
<p>.NET support can be divided into a three tiered hierarchy:</p>
<p><em>Tier One</em> – It must be possible for a .NET client program to store .NET objects to the cache, retrieve them from the cache, and operate on them.  This is the sine qua non of .NET support in a caching product.</p>
<p><em>Tier Two</em> – For caching products that allow the user (developer) to implement server-side processing that is closely integrated with the cache, the second tier of .NET support lets the developer implement the server-side logic in a .NET language.</p>
<p><em>Tier Three</em> – A caching product could be implemented entirely in a .NET language and be fully harmonized with the broader .NET ecosystem. As we have already observed, none of the best known products are built this way.</p>
<p>An orthogonal consideration – supported languages – can be applied to all three tiers.  Compatibility with one .NET language doesn’t imply compatibility with all .NET languages; cross-language interoperability depends on compliance with Microsoft’s Common Language Specification (CLS) <a href="http://msdn.microsoft.com/en-us/library/730f1wy3(v=vs.71).aspx">http://msdn.microsoft.com/en-us/library/730f1wy3(v=vs.71).aspx</a>.  So, although C# is likely to be the language of interest for most organizations that are looking for a .NET-compatible distributed caching solution, it is worth noting whether or not the .NET support provided in these products extends to other .NET languages as well.</p>
<h3>GigaSpaces XAP .NET</h3>
<p>First, a refresher on XAP:  This GigaSpaces product began as a distributed caching framework designed to reduce latency when accessing application data, be highly scalable, and simplify the construction of “real-time” (event-driven) systems.  Unlike most caches which are based on the key – value paradigm, GigaSpaces is based on Java spaces, which is an implementation of tuple spaces <a href="http://en.wikipedia.org/wiki/Tuple_space">http://en.wikipedia.org/wiki/Tuple_space</a>.  Tuples provide more generalized data matching features than do key – value pairs, and tuple spaces feature strong, built-in concurrency controls.</p>
<p>As new capabilities were added, the XAP framework evolved from a caching system to a full-featured application development and management platform.  In addition to highly available caching,  XAP now provides several server-side processing options, event notification and distribution, an SLA-based managed execution environment, dynamic scalability, multi-site replication and – of course &#8211; .NET support.</p>
<p>In the terminology of the framework described in the previous section, XAP .NET provides tiers one and two functionality, with support for C# and Visual Basic (VB .NET).</p>
<h4>Tier One Support</h4>
<p>XAP .NET includes a C# API for use when writing a caching client.  The API provides classes and methods for creating or connecting to a cache, writing data to the cache, reading data from the cache, and querying or searching the cache for objects that match specific criteria.  Transactional and concurrency control features are also available for use when needed.</p>
<h4>Tier Two Support</h4>
<p>Server side application logic can be implemented for execution on demand or in response to data events or conditions with GigaSpaces .NET. On-demand logic takes the form of remote procedure calls.  Processing logic is implemented in C#, as is the interface contract.  Clients use features of the C# API to invoke the remote procedures.</p>
<p>Event driven logic can be implemented as either a polling mechanism or an event notification mechanism.  The polling conditions or event registration (depending on which mechanism is in use) are specified in C#, as is handler code that receives the result of the polling operation or is notified of the data event.</p>
<p>Note that the client program that triggers the server-side event need not be a .NET program.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=199</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Four Coherence-based Solutions to a Data Hot Spot Problem</title>
		<link>http://blog.scapps.co.uk/?p=172</link>
		<comments>http://blog.scapps.co.uk/?p=172#comments</comments>
		<pubDate>Wed, 31 Aug 2011 18:25:57 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Oracle Coherence]]></category>
		<category><![CDATA[What I'm Working On]]></category>
		<category><![CDATA[Coherence]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[throughput]]></category>
		<category><![CDATA[transactions]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=172</guid>
		<description><![CDATA[Summary Leveraging the DICE framework I developed last year (write-up available under “Papers and Articles” at http://www.scapps.co.uk), I developed four different solutions to a simplified (non-distributed) variant of the DICE computing problem using Coherence 3.7, each using a different approach to concurrency management. I then measured the throughput of each implementation using DICE configurations that [...]]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: left;" align="CENTER"><span class="Apple-style-span" style="font-family: 'Arundina Sans'; font-weight: normal; font-size: medium;"><strong>Summary</strong></span></h1>
<div style="text-align: -webkit-auto;">
<p align="LEFT"><span style="font-size: x-small;"><span style="font-size: medium;">Leveraging the DICE framework I developed last year (write-up available under “Papers and Articles” at </span><a href="http://www.scapps.co.uk/"><span style="color: #800000;"><span style="font-size: medium;">http://www.scapps.co.uk</span></span></a><span style="font-size: medium;">), I developed four different solutions to a simplified (non-distributed) variant of the DICE computing problem using Coherence 3.7, each using a different approach to concurrency management. I then measured the throughput of each implementation using DICE configurations that promote a high rate of concurrent requests for access to shared data objects.</span></span></p>
<p align="LEFT"><span style="font-size: medium;">The implementation based on Coherence&#8217;s Entry Processors feature showed the highest throughput.</span></p>
<p align="LEFT"><span style="font-size: medium;">Two of the four implementations provide ACID transactional guarantees. The transactional implementations provided lower throughput than the non-transactional implementations. </span></p>
<p align="LEFT"><span style="font-size: medium;">One of the two transactional implementations uses a Coherence transactionality feature which is now deprecated. The other uses Coherence&#8217;s new Transactions Framework. The transactional implementation based on the deprecated Coherence feature provided greater throughput than the implementation based on the new Transaction Framework.</span></p>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>Simplified DICE Computing Problem</strong></span></span></p>
<p><span style="font-size: medium;">There are two domain classes: </span></p>
<ul>
<li><span style="font-size: medium;">Counters, each with a unique identifier and a counter value.</span></li>
<li><span style="font-size: medium;">Incrementers, each containing a unique identifier and a reference to a Counter, and a flag that is used to distinguish between Incrementers that have and have not been processed. Each Incrementer represents an event to be processed.</span></li>
</ul>
<p><span style="font-size: medium;">Processing an Incrementer event involves the following steps: </span></p>
<ol>
<li><span style="font-size: medium;">The Incrementer object is interrogated to obtain the id of the Counter object to which it refers. </span></li>
<li><span style="font-size: medium;">The Counter object is located. </span></li>
<li><span style="font-size: medium;">The value of the Counter object&#8217;s counter field is incremented. </span></li>
<li><span style="font-size: medium;">The Incrementer object&#8217;s processed flag is set. </span></li>
<li><span style="font-size: medium;">The new state of the Counter is saved in the shared data area. </span></li>
<li><span style="font-size: medium;">The Incrementer is written to the shared data area. </span><span style="font-size: medium;">The throughput being measured is the rate at which these update operations (DICE ops.) are performed. </span></li>
</ol>
<p><span style="font-size: medium;">This problem is a simplified version of the original DICE problem, which required that domain data and processing be distributed across more than one host. In the simplified version presented here, all data is stored and all processing is done on a single host. Note, however, that the solutions presented here can also work without modification with distributed clients, data or both.</span></p>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>The Four Implementations</strong></span></span></p>
<p><span style="font-size: medium;">The client program in each of the four implementations is a cluster member without local storage. The cache(s) needed by each implementation are established and managed by another cluster member which is started before the client is run. </span></p>
<p><span style="font-size: medium;">The four implementations differ in the ways they perform DICE ops:</span></p>
<ul>
<li><span style="font-size: medium;">Client non-transactional – The client&#8217;s worker threads read from and write to the caches, using explicit locks to manage concurrency. Two caches are used, one per domain type.</span></li>
<li><span style="font-size: medium;">EntryProcessor non-transactional – The client&#8217;s worker threads send Entry Processors to the cluster member that hosts the data. That cluster member performs the updates, taking advantage of the Entry Processors&#8217; inherent concurrency controls. One cache is used for both domain types so that a single Entry Processor can be used for each DICE op.</span></li>
<li><span style="font-size: medium;">Client transactional deprecated &#8211; The client&#8217;s worker threads read from and write to the caches using the (deprecated) TransactionMap interface. Pessimistic mode is used to manage concurrency. Two caches are used, one per domain type.</span></li>
<li><span style="font-size: medium;">Client transactional Transaction Framework &#8211; The client&#8217;s worker threads read from and writes to the caches using the Transaction Framework&#8217;s OptimisticNamedCache interface. When updates fail for concurrency-related reasons (either a required lock is unavailable or the optimistic assumption proves false), retries are issued automatically. Two caches are used, one per domain type.</span></li>
</ul>
<p><span style="font-size: medium;">Each DICE Op. Includes two writes to the cache: a Counter is updated, and an Incrementer is inserted. In the two transactional implementations, these writes are performed as an atomic operation. In the non-transactional implementation they are not.</span></p>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>DICE Configuration</strong></span></span></p>
<p><span style="font-size: medium;">Here are some key points from the DICE application configuration used for these tests:</span></p>
<ul>
<li><span class="Apple-style-span" style="font-size: medium;">The number of Counter objects was set to two for one series of tests, and to ten for another series (as shown in the table of results).</span></li>
<li><span style="font-size: medium;">One client instance was run for each test execution.</span></li>
<li><span style="font-size: medium;">The client spawned five worker threads that initiated DICE ops.</span></li>
<li><span style="font-size: medium;">Each thread was instructed to execute 2,000 DICE ops.<br />
(The total number of DICE ops. per test was therefore 5 x 2,000 = 10,000.)</span></li>
<li><span style="font-size: medium;">Counter objects each contain a string field that can be populated to increase the size of each instance. For these tests a string of 4,096 bytes was used.</span></li>
</ul>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>Coherence Cache Configuration</strong></span></span></p>
<p><span style="font-size: medium;">Here are some key points from the Coherence cache configuration used for these tests:</span></p>
<p><span style="font-size: medium;">A distributed scheme managed by the DistributedCache service was used for the two non-transactional implementations and the transactional implementation based on the deprecated TransactionMap interface. </span></p>
<ul>
<li><span style="font-size: medium;">A transactional scheme managed by the TransactionalCache service was used for the TransactionMap implementation.</span></li>
<li><span style="font-size: medium;">In both cases, thread-count was set to two; lease-granularity was set to &#8216;lease&#8217;; and an unlimited backing map local scheme was used.</span></li>
</ul>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>Observed Throughput</strong></span></span></p>
<p><span style="font-size: medium;">The Coherence license under which I am working does not allow me to “disclose results of any program benchmark tests without our prior consent”. Because I don&#8217;t have Oracle&#8217;s consent to publish my observations, I am reporting results on a relative basis, with the throughput rates I observed indexed to the lowest value.</span></p>
<p><span style="font-size: medium;">Several iterations of the test were run with each implementation. The table that follows shows the best throughput achieved by each implementation with two and five Counters respectively, indexed to the throughput of the lowest observed rate (Transaction Framework with two Counters).</span></p>
<table width="636" cellspacing="0" cellpadding="2">
<colgroup>
<col width="419" />
<col width="100" />
<col width="104" /> </colgroup>
<tbody>
<tr>
<td width="419" height="27">
<p align="CENTER"><span style="font-size: medium;"><strong>implementation</strong></span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;"><strong>no. Counters</strong></span></p>
</td>
<td width="104">
<p align="CENTER"><span style="font-size: medium;"><strong><span style="font-family: 'Liberation Sans', sans-serif;">indexed throughput </span></strong></span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">EntryProcessor non-transactional</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">2</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">11.7</span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">client non-transactional</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">2</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">3.7</span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">client transactional deprecated</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">2</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">2.4</span></p>
</td>
</tr>
<tr>
<td valign="BOTTOM" width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">client transactional Transaction Framework</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">2</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">1.0</span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">EntryProcessor non-transactional</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">10</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">12.1</span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">client non-transactional</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">10</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">5.3</span></p>
</td>
</tr>
<tr>
<td width="419" height="13">
<p align="LEFT"><span style="font-size: medium;">client transactional deprecated</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">10</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">3.1</span></p>
</td>
</tr>
<tr>
<td valign="BOTTOM" width="419" height="12">
<p align="LEFT"><span style="font-size: medium;">client transactional Transaction Framework</span></p>
</td>
<td width="100">
<p align="CENTER"><span style="font-size: medium;">10</span></p>
</td>
<td valign="BOTTOM" width="104">
<p align="RIGHT"><span style="font-size: medium;">2.1</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: medium;">When considering these results it is important to remember that:</span></p>
<ul>
<li>
<p align="LEFT"><span style="font-size: medium;">Throughput was measured using a DICE configuration designed to produce very heavy contention for access to a small number of data elements. </span></p>
</li>
<li>
<p align="LEFT"><span style="font-size: medium;">Neither the execution environment nor the Coherence configuration were tuned to optimize the throughput of any of the implementations. </span></p>
</li>
</ul>
<p><span style="font-family: 'Arundina Sans';"><span style="font-size: medium;"><strong>Conclusions and Interpretation</strong></span></span></p>
<p><span style="font-size: medium;">Higher rates of throughput were achieved by the non-transactional implementations than by the transactional implementations. Presumably this is because of the overhead required to support the atomicity and isolation properties of transactions.</span></p>
<p><span style="font-size: medium;">Of the two non-transactional implementations, the implementation that used EntryProcessors provided greater throughput by a factor of more than two. This advantage is likely attributable to the smaller amount of inter-process communication required by the Entry Processors compared with the non-transactional client implementation. </span></p>
<p><span style="font-size: medium;">Of the two transactional implementations, the one based on the deprecated TransactionMap feature showed greater throughput. This is probably because its pessimistic mode is more efficient than the Transaction Framework&#8217;s optimistic concurrency control for this use-case, which is write-intensive and contention-intensive by design.</span></p>
<p><span style="font-size: medium;">As shown in the following table, each implementation achieved greater throughput when the number of Counters was increased (although in the case of the EntryProcessor implementation the increase was only about 4%). The reduced rate of contention for each Counter probably explains the increases.</span></p>
<table width="491" cellspacing="0" cellpadding="2">
<colgroup>
<col width="409" />
<col width="72" /> </colgroup>
<tbody>
<tr>
<td width="409">
<p align="CENTER"><span style="font-size: medium;"><strong>implementation</strong></span></p>
</td>
<td width="72">
<p align="CENTER"><span style="font-size: medium;"><strong>% change</strong></span></p>
</td>
</tr>
<tr>
<td width="409">
<p align="LEFT"><span style="font-size: medium;">EntryProcessor non-transactional</span></p>
</td>
<td valign="BOTTOM" width="72">
<p align="RIGHT"><span style="font-size: medium;">4%</span></p>
</td>
</tr>
<tr>
<td width="409">
<p align="LEFT"><span style="font-size: medium;">client non-transactional</span></p>
</td>
<td valign="BOTTOM" width="72">
<p align="RIGHT"><span style="font-size: medium;">42%</span></p>
</td>
</tr>
<tr>
<td width="409">
<p align="LEFT"><span style="font-size: medium;">client transactional deprecated</span></p>
</td>
<td valign="BOTTOM" width="72">
<p align="RIGHT"><span style="font-size: medium;">33%</span></p>
</td>
</tr>
<tr valign="BOTTOM">
<td width="409">
<p align="LEFT"><span style="font-size: medium;">client transactional Transaction Framework</span></p>
</td>
<td width="72">
<p align="RIGHT"><span style="font-size: medium;">134%</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: medium;">The percentage improvement in throughput when the number of counters was increased was greatest (134%) for the Transaction Framework implementation. The likely explanation is that the cost of the retries used by this implementation to recover from concurrency conflicts is very high. With the updates spread across five times as many Counters the number of retries was substantially reduced.</span></p>
<p><span style="font-size: medium;">As the following table show, the throughput advantage of the implementation using the deprecated TransactionMap feature over the implementation using the newer Transaction Framework became much smaller percentage-wise when the number of Counters was increased from two to ten. This observation suggests that the retries employed by the Transaction Framework implementation to resolve concurrency conflicts account for most of the difference in throughput rates between the old and new transactionality features.</span></p>
<dl>
<dd>
<table width="254" cellspacing="0" cellpadding="2">
<colgroup>
<col width="138" />
<col width="106" /> </colgroup>
<tbody>
<tr>
<td width="138">
<p align="CENTER"><span style="font-size: medium;"><strong>Counters</strong></span></p>
</td>
<td width="106">
<p align="CENTER"><span style="font-size: medium;"><strong>% increase</strong></span></p>
</td>
</tr>
<tr>
<td width="138" height="13">
<p align="LEFT"><span style="font-size: medium;">Two Counters</span></p>
</td>
<td width="106">
<p align="RIGHT"><span style="font-size: medium;">136%</span></p>
</td>
</tr>
<tr>
<td width="138" height="12">
<p align="LEFT"><span style="font-size: medium;">Ten Counters</span></p>
</td>
<td width="106">
<p align="RIGHT"><span style="font-size: medium;">34%</span></p>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<p>&nbsp;</p>
<p><span style="font-family: Consolas, Monaco, monospace;"><span class="Apple-style-span" style="font-size: 12px; font-weight: normal; line-height: 18px; white-space: pre;"><br />
</span></span></p>
</div>
<h1 align="CENTER"></h1>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=172</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lightning Talk at CloudCamp</title>
		<link>http://blog.scapps.co.uk/?p=92</link>
		<comments>http://blog.scapps.co.uk/?p=92#comments</comments>
		<pubDate>Sun, 30 Aug 2009 12:21:24 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[GigaSpaces]]></category>
		<category><![CDATA[Terracotta]]></category>
		<category><![CDATA[CloudCamp]]></category>
		<category><![CDATA[Skills Matter]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=92</guid>
		<description><![CDATA[Video of a five minute talk about GigaSpaces and Terracotta at London's CloudCamp]]></description>
			<content:encoded><![CDATA[<p>Last month I gave a five minute talk about GigaSpaces and Terracotta at London&#8217;s CloudCamp, an event which was well organized, well attended and well received. If you care to see my talk, follow this link:</p>
<p>http://skillsmatter.com/podcast/cloud-grid/refreshment-break-select-breakout-session</p>
<p>(videos generously hosted by the folks at Skills Matter).  Click around and you&#8217;ll find a lot more good content.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=92</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Illustration of Terracotta Locking Strategies</title>
		<link>http://blog.scapps.co.uk/?p=83</link>
		<comments>http://blog.scapps.co.uk/?p=83#comments</comments>
		<pubDate>Sun, 28 Jun 2009 18:09:57 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Terracotta]]></category>
		<category><![CDATA[locking]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[transactions]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=83</guid>
		<description><![CDATA[A very simple illustration of the impact that the choice of locking strategy can have on a Terracotta application's performance.]]></description>
			<content:encoded><![CDATA[<p>If you are familiar with Terracotta then you know that its hallmark feature is  data sharing between Java programs running on different virtual machines.  Making use of this very powerful capability requires that the the programs that  share the data use Java synchronization to prevent conflicts between operations that access the shared data from corrupting the data or returning incomplete results.  Terracotta data sharing also requires that Terracotta be configured to detect and honour the Java synchronization instructions. In this post we refer to the combination of Java synchronization and Terracotta configuration as a “locking strategy”.</p>
<p>The choice of locking strategy can have a profound impact on a Terracotta application&#8217;s  performance.  Even in a very simple application, there may be several points of data contention at which locking strategies are required, and several possible locking strategies for each contention point.   This post provides a very brief illustration of how locking strategies are implemented with Terracotta, and of the impact that a small change in locking strategy can have on  application performance.</p>
<p>This post barely scratches the surface of Terracotta&#8217;s remarkable data sharing capabilities, and it completely bypasses many other powerful and important features of the product.  Readers are advised to regard  this post as a very simple illustration of some basic principles of working with Terracotta, and nothing more.</p>
<p>Readers should also understand that this post demonstrates use of Terracotta&#8217;s low level concurrency features.  Many Terracotta users will find themselves using Terracotta&#8217;s integration modules (TIMS), which provide out-of-the-box integration with productivity frameworks such as Hibernate and Spring.  The intent of the developers of these integration modules seems to be to shield users of the module as much as possible from the kinds of low level concurrency concerns that feature prominently in this post.</p>
<p>As a starting point, we create two Java programs from three classes:<br />
A &#8211; a data POJO.<br />
TCLockingExampleMain &#8211; a program that creates and instance of A and updates A&#8217;s data field.<br />
TCLockingExampleReporter – a program that indicates whether or not our data is shareable.</p>
<p>Here is the source code for all three classes prior to implementing any locking strategy:</p>
<p>package tcLockingExample;</p>
<p>public class A {<br />
int primInt;</p>
<p>public void primIntInc() {<br />
this.primInt++;<br />
}<br />
}</p>
<p>package tcTLockingExample;</p>
<p>public class TCLockingExampleMain {<br />
static A aInstance = new A();</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
for (int x = 0; x &lt; 10; x++ ) {<br />
aInstance.primIntInc();<br />
System.out.println(&#8220;aInstance.primInt: &#8221; + aInstance.primInt);<br />
}<br />
}<br />
}</p>
<p>package tcTLockingExample;</p>
<p>import java.util.Date;</p>
<p>public class TCLockingExampleReporter {</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
System.out.println(new Date() + &#8221; TCLockingChoicesMain.aInstance.primInt:&#8221; + TCLockingExampleMain.aInstance.primInt);<br />
}<br />
}</p>
<p>We will be tinkering with the first two classes as the example progresses.</p>
<p>The first step is to establish that the programs work as expected when run without Terracotta.  As the following output illustrates, both programs run:</p>
<p>aInstance.primInt: 1<br />
aInstance.primInt: 2<br />
aInstance.primInt: 3<br />
aInstance.primInt: 4<br />
aInstance.primInt: 5<br />
aInstance.primInt: 6<br />
aInstance.primInt: 7<br />
aInstance.primInt: 8<br />
aInstance.primInt: 9<br />
aInstance.primInt: 1</p>
<p>but, of course, there is no data sharing between them:</p>
<p>Sun Jun 07 17:48:16 BST 2009 TCLockingChoicesMain.aInstance.primInt:0</p>
<p>Next we run each prgram as a Terracotta application, but without configuring Terracotta to share data between them.  The results are the same:</p>
<p>2009-06-07 18:06:48,029 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:06:48,334 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:06:48,494 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:06:49,907 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
aInstance.primInt: 1<br />
aInstance.primInt: 2<br />
aInstance.primInt: 3<br />
aInstance.primInt: 4<br />
aInstance.primInt: 5<br />
aInstance.primInt: 6<br />
aInstance.primInt: 7<br />
aInstance.primInt: 8<br />
aInstance.primInt: 9<br />
aInstance.primInt: 10</p>
<p>and from TCLockingExampleReporter:</p>
<p>2009-06-07 18:09:03,467 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:09:03,772 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:09:03,905 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:09:05,199 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
Sun Jun 07 18:09:05 BST 2009 TCLockingChoicesMain.aInstance.primInt:0</p>
<p>Next we configure Terracotta to be aware of all three classes, and set a trap for ourselves by establishing the instance of A  in TCLockingExampleMain as a root class (a Terracotta root is an object that is identified as shared by the application&#8217;s Terracotta configuration):</p>
<p>&lt;dso&gt;<br />
&lt;instrumented-classes&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcTLockingExample.A&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcTLockingExample.TCLockingExampleMain&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcTLockingExample.TCLockingExampleReporter&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;/instrumented-classes&gt;<br />
&lt;roots&gt;<br />
&lt;root&gt;<br />
&lt;field-name&gt;tcTLockingExample.TCLockingExampleMain.aInstance&lt;/field-name&gt;<br />
&lt;/root&gt;<br />
&lt;/roots&gt;<br />
&lt;/dso&gt;</p>
<p>This is a trap because, having established  TCLockingExampleMain.aInstance as a shared object, we are obliged to implement a locking strategy wherever we write to it in our code.  Because we have not done this,   TCLockingExampleMain fails:</p>
<p>2009-06-07 18:13:48,927 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:13:49,240 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:13:49,371 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:13:50,845 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
com.tc.object.tx.UnlockedSharedObjectException:<br />
*********************************************************************<br />
Attempt to access a shared object outside the scope of a shared lock.<br />
All access to shared objects must be within the scope of one or more<br />
shared locks defined in your Terracotta configuration.</p>
<p>Caused by Thread: main in VM(0)<br />
Shared Object Type: tcTLockingExample.A</p>
<p>The cause may be one or more of the following:<br />
* Terracotta locking was not configured for the shared code.<br />
* The code itself does not have synchronization that Terracotta<br />
can use as a boundary.<br />
* The class doing the locking must be included for instrumentation.<br />
* The object was first locked, then shared.</p>
<p>For more information on how to solve this issue, see:</p>
<p>http://www.terracotta.org/usoe</p>
<p>*********************************************************************</p>
<p>at com.tc.object.tx.ClientTransactionManagerImpl.getTransaction(ClientTransactionManagerImpl.java:360)<br />
at com.tc.object.tx.ClientTransactionManagerImpl.fieldChanged(ClientTransactionManagerImpl.java:653)<br />
at com.tc.object.TCObjectImpl.objectFieldChanged(TCObjectImpl.java:317)<br />
at com.tc.object.TCObjectImpl.intFieldChanged(TCObjectImpl.java:357)<br />
at tcTLockingExample.A.__tc_setprimInt(A.java)<br />
at tcTLockingExample.A.primIntInc(A.java:7)<br />
at tcTLockingExample.TCLockingExampleMain.main(TCLockingExampleMain.java:11)<br />
Exception in thread &#8220;main&#8221; com.tc.object.tx.UnlockedSharedObjectException:<br />
*********************************************************************<br />
Attempt to access a shared object outside the scope of a shared lock.<br />
All access to shared objects must be within the scope of one or more<br />
shared locks defined in your Terracotta configuration.</p>
<p>Caused by Thread: main in VM(0)<br />
Shared Object Type: tcTLockingExample.A</p>
<p>The cause may be one or more of the following: . . .</p>
<p>To fix this we will implement our first locking strategy, by synchronizing the method in A that writes to the data member of the shared instance:<br />
package tcLockingExample;</p>
<p>public class A {<br />
int primInt;</p>
<p>synchronized public void primIntInc() {<br />
this.primInt++;<br />
}<br />
}</p>
<p>and configuring Terracotta to apply its locking to that method:</p>
<p>&lt;dso&gt;<br />
&lt;instrumented-classes&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcLockingExample.A&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcLockingExample.TCLockingExampleMain&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcLockingExample.TCLockingExampleReporter&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;/instrumented-classes&gt;<br />
&lt;roots&gt;<br />
&lt;root&gt;<br />
&lt;field-name&gt;tcLockingExample.TCLockingExampleMain.aInstance&lt;/field-name&gt;<br />
&lt;/root&gt;<br />
&lt;/roots&gt;<br />
&lt;locks&gt;<br />
&lt;autolock&gt;<br />
&lt;method-expression&gt;void tcLockingExample.A.primIntInc()&lt;/method-expression&gt;<br />
&lt;lock-level&gt;write&lt;/lock-level&gt;<br />
&lt;/autolock&gt;<br />
&lt;/locks&gt;<br />
&lt;/dso&gt;</p>
<p>Now TCLockingExampleMain works:</p>
<p>2009-06-07 18:24:22,965 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:24:23,284 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:24:23,414 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:24:25,324 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
aInstance.primInt: 1<br />
aInstance.primInt: 2<br />
aInstance.primInt: 3<br />
aInstance.primInt: 4<br />
aInstance.primInt: 5<br />
aInstance.primInt: 6<br />
aInstance.primInt: 7<br />
aInstance.primInt: 8<br />
aInstance.primInt: 9<br />
aInstance.primInt: 10</p>
<p>and TCLockingExampleReporter shows that the data is being shared:</p>
<p>2009-06-07 18:27:21,486 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:27:21,804 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:27:21,933 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:27:23,271 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
Sun Jun 07 18:27:23 BST 2009 TCLockingChoicesMain.aInstance.primInt:10</p>
<p>Next we try a different locking strategy.  We remove the synchronization from A&#8217;s method, and instead synchronize TCLockingExampleMain&#8217;s write operation on the root object:</p>
<p>package tcLockingExample;</p>
<p>public class TCLockingExampleMain {<br />
static A aInstance = new A();</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
for (int x = 0; x &lt; 10; x++ ) {<br />
synchronized(aInstance) {<br />
aInstance.primIntInc();<br />
}<br />
System.out.println(&#8220;aInstance.primInt: &#8221; + aInstance.primInt);<br />
}<br />
}<br />
}</p>
<p>We also update the Terracotta configuration, applying a Terracotta autolock (which means that Terracotta will add its locking wherever it sees Java synchronization) to TCLockingExampleMain&#8217;s main() method instead of A&#8217;s incrementer method:</p>
<p>&lt;dso&gt;<br />
&lt;instrumented-classes&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcLockingExample.A&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;include&gt;<br />
&lt;class-expression&gt;tcLockingExample.TCLockingExampleMain&lt;/class-expression&gt;<br />
&lt;/include&gt;<br />
&lt;/instrumented-classes&gt;<br />
&lt;roots&gt;<br />
&lt;root&gt;<br />
&lt;field-name&gt;tcLockingExample.TCLockingExampleMain.aInstance&lt;/field-name&gt;<br />
&lt;/root&gt;<br />
&lt;/roots&gt;<br />
&lt;locks&gt;<br />
&lt;autolock&gt;<br />
&lt;method-expression&gt;void tcLockingExample.TCLockingExampleMain.main(java.lang.String[])&lt;/method-expression&gt;<br />
&lt;lock-level&gt;write&lt;/lock-level&gt;<br />
&lt;/autolock&gt;<br />
&lt;/locks&gt;<br />
&lt;/dso&gt;</p>
<p>This strategy also works:<br />
2009-06-07 18:45:39,099 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:45:39,425 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:45:39,555 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:45:41,441 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
aInstance.primInt: 1<br />
aInstance.primInt: 2<br />
aInstance.primInt: 3<br />
aInstance.primInt: 4<br />
aInstance.primInt: 5<br />
aInstance.primInt: 6<br />
aInstance.primInt: 7<br />
aInstance.primInt: 8<br />
aInstance.primInt: 9<br />
aInstance.primInt: 10</p>
<p>and data sharing is enabled:<br />
2009-06-07 18:44:17,498 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 18:44:17,816 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 18:44:17,951 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 18:44:19,710 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
Sun Jun 07 18:44:19 BST 2009 TCLockingChoicesMain.aInstance.primInt:10</p>
<p>Finally we&#8217;ll take a quick look at how the choice of locking strategy can affect performance.  To see this, we change  TCLockingExampleMain so it increments A&#8217;s integer member a million times instead of ten as in previous executions.  We also add some code to tell us how long the program took to do the million iterations:</p>
<p>package tcLockingExample;</p>
<p>import java.util.Date;</p>
<p>public class TCLockingExampleMain {<br />
static A aInstance = new A();</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
Date startTime = new Date();<br />
for (int x = 0; x &lt; 1000000; x++) {<br />
aInstance.primIntInc();<br />
}<br />
Date endTime = new Date();<br />
System.out.println(&#8220;startTime: &#8221; + startTime + &#8221; endTime: &#8221; + endTime<br />
+ &#8221; elapsed: &#8221;<br />
+ ((endTime.getTime() &#8211; startTime.getTime()) / 1000)<br />
+ &#8221; seconds&#8221;);<br />
System.out.println(&#8220;aInstance.primInt: &#8221; + aInstance.primInt);<br />
}<br />
}</p>
<p>When we run this program we see that the million iterations take around 26 seconds:</p>
<p>2009-06-07 19:16:09,091 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 19:16:09,410 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 19:16:09,544 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 19:16:11,022 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
startTime: Sun Jun 07 19:16:11 BST 2009 endTime: Sun Jun 07 19:16:37 BST 2009 elapsed: 26 seconds<br />
aInstance.primInt: 1000000</p>
<p>Next we try our second locking strategy with a million iterations:</p>
<p>package tcLockingExample;</p>
<p>import java.util.Date;</p>
<p>public class TCLockingExampleMain {<br />
static A aInstance = new A();</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
Date startTime = new Date();<br />
for (int x = 0; x &lt; 1000000; x++) {<br />
synchronized (aInstance) {<br />
aInstance.primIntInc();<br />
}<br />
}<br />
Date endTime = new Date();<br />
System.out.println(&#8220;startTime: &#8221; + startTime + &#8221; endTime: &#8221; + endTime<br />
+ &#8221; elapsed: &#8221;<br />
+ ((endTime.getTime() &#8211; startTime.getTime()) / 1000)<br />
+ &#8221; seconds&#8221;);<br />
System.out.println(&#8220;aInstance.primInt: &#8221; + aInstance.primInt);<br />
}<br />
}</p>
<p>It takes about the same amount of time:</p>
<p>2009-06-07 19:21:08,279 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 19:21:08,602 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 19:21:08,737 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 19:21:10,266 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
startTime: Sun Jun 07 19:21:10 BST 2009 endTime: Sun Jun 07 19:21:37 BST 2009 elapsed: 26 seconds<br />
aInstance.primInt: 1000000</p>
<p>For our last test we move the synchronization statement outside of the loop, meaning that only one lock is required instead of a million (one per iteration):</p>
<p>package tcLockingExample;</p>
<p>import java.util.Date;</p>
<p>public class TCLockingExampleMain {<br />
static A aInstance = new A();</p>
<p>/**<br />
* @param args<br />
*/<br />
public static void main(String[] args) {<br />
Date startTime = new Date();<br />
synchronized (aInstance) {<br />
for (int x = 0; x &lt; 1000000; x++) {<br />
aInstance.primIntInc();<br />
}<br />
}<br />
Date endTime = new Date();<br />
System.out.println(&#8220;startTime: &#8221; + startTime + &#8221; endTime: &#8221; + endTime<br />
+ &#8221; elapsed: &#8221;<br />
+ ((endTime.getTime() &#8211; startTime.getTime()) / 1000)<br />
+ &#8221; seconds&#8221;);<br />
System.out.println(&#8220;aInstance.primInt: &#8221; + aInstance.primInt);<br />
}<br />
}</p>
<p>Execution time drops from 26 seconds to less than one second:</p>
<p>2009-06-07 19:23:52,409 INFO &#8211; Terracotta 3.0.0, as of 20090410-200435 (Revision 12431 by cruise@su10mo5 from 3.0)<br />
2009-06-07 19:23:52,727 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/TCLockingExample/tc-config.xml&#8217;.<br />
2009-06-07 19:23:52,861 INFO &#8211; Log file: &#8216;/home/dan/workspace/TCLockingExample/terracotta/client-logs/terracotta-client.log&#8217;.<br />
2009-06-07 19:23:54,335 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510<br />
startTime: Sun Jun 07 19:23:54 BST 2009 endTime: Sun Jun 07 19:23:55 BST 2009 elapsed: 0 seconds<br />
aInstance.primInt: 1000000</p>
<p>As these very simple examples show, there are often several choices for how to implement locking in a Terracotta application, and the selection of a strategy can have profound implications for application performance.  For a developer who is new to Terracotta, selecting appropriate locking strategies may involve significant amounts of trial and error.  As the developer&#8217;s understanding of Terracotta grows with experience, locking strategy selection becomes easier and less experimentation is required.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=83</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Exercising Terracotta&#8217;s Virtual Heap</title>
		<link>http://blog.scapps.co.uk/?p=74</link>
		<comments>http://blog.scapps.co.uk/?p=74#comments</comments>
		<pubDate>Mon, 01 Jun 2009 20:03:36 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Terracotta]]></category>
		<category><![CDATA[virtual heap]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=74</guid>
		<description><![CDATA[A quick investigation into Terracotta's virtual heap capability, with source code for download.]]></description>
			<content:encoded><![CDATA[<p>Chapter 4 of <span style="font-style: normal;"><span style="text-decoration: underline;">The Definitive Guide to Terracotta</span></span> says:</p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><em>When you traverse a reference to a clustered object that isn&#8217;t currently instantiated on the local physical heap, Terracotta will automatically request that object&#8217;s data from the Terracotta server, instantiate it on the local heap, and wire up the reference you are traversing, and your application will be none the wiser.</em></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><em> Likewise, Terracotta can artificially add </em><span><em>null</em></span><em> references to clustered objects as memory pressure increases, which lets arbitrarily large clustered object graphs fit within a constrained physical heap space.</em></p>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">I ran a couple of experiments to help me understand how these capabilities translate into application behaviour. You can download the source code for the simple Java programs I used in these experiments <a href="../wp-content/uploads/2009/05/bigHeap.jar">here</a>.</p>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">The first question I wanted to answer was whether or not Terracotta&#8217;s ability to page heap objects in and out would allow a Terracotta client to create an object graph that was too big for its physical heap. The book states that a program can <em>traverse</em> an object graph that is too large for its heap, but it does not claim that the virtualization effect applies to object creation. Nevertheless I thought the possibility was worth investigating.</p>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">
<p style="margin-bottom: 0cm; font-style: normal;" align="left">I designed the experiment to test this as follows:</p>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">
<ol>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">Determine how many instances of a class of a fixed size (just over 3 kB) can be created and added to a HashMap by a non-Terracotta Java application running with a heap space of a known size before the application runs out of heap space.</p>
</li>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left">D<span style="font-style: normal;">etermine how many instances of the same fixed size class can be created by the same Java application running as a Terracotta client application with the HashMap holding the object instances configured as a Terracotta root, and with a heap space of the same known size.</span></p>
</li>
</ol>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">I foresaw two possible outcomes:</p>
<ol>
<li>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">The numbers of objects created by the two programs would be about the same, indicating that Terracotta&#8217;s ability to relieve memory pressure does not apply to pressure caused by the creation of new objects.</p>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">The Terracotta client would be able to create many more instances of the test object than its plain Java counterpart did, indicating that Terracotta&#8217;s object paging feature detects and handles memory pressure caused by the creation of new objects.</p>
</li>
</ol>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">The actual results matched the second of the scenarios I had envisioned. When I ran the test with a heap size of 100 megabytes, the plain Java client created 2,988 instances of the test object before running out of memory.</p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>dan@scapps1:~/workspace/bigHeap$ java -Xms100m -Xmx100m -classpath ./bin bigHeap.BigHeapMain 2988 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 1000 total memory: 100532224 free memory: 68213168 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 2000 total memory: 100532224 free memory: 36038896 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span><span style="font-style: normal;"><span style="text-decoration: none;">dan@scapps1:~/workspace/bigHe</span></span></span><span><span style="font-style: normal;"><span style="text-decoration: none;">ap$ </span></span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">Running as a Terracotta client, the program successfully instantiated more than 11,000 instances running with a server provisioned with 512 megabytes of heap:</p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>dan@scapps1:~/workspace/bigHeap$ dso-java.sh -Xms100m -Xmx100m -classpath ./bin bigHeap.BigHeapMain 11010 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Starting BootJarTool&#8230; </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:30,423 INFO &#8211; Terracotta 3.0.0, as of 20090409-180411 (Revision 12431 by cruise@su10mo5 from 3.0) </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:30,748 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/bigHeap/tc-config.xml&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Starting Terracotta client&#8230; </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:32,353 INFO &#8211; Terracotta 3.0.0, as of 20090409-180411 (Revision 12431 by cruise@su10mo5 from 3.0) </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:32,673 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/bigHeap/tc-config.xml&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:32,804 INFO &#8211; Log file: &#8216;/home/dan/workspace/bigHeap/terracotta/client-logs/terracotta-client.log&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:08:34,786 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 1000 total memory: 93257728 free memory: 39313736 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 2000 total memory: 93257728 free memory: 34530984 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 3000 total memory: 93257728 free memory: 33617040 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 4000 total memory: 93323264 free memory: 36051464 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 5000 total memory: 93257728 free memory: 24922912 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 6000 total memory: 93061120 free memory: 10904496 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 7000 total memory: 93257728 free memory: 39410008 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 8000 total memory: 93257728 free memory: 32656648 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 9000 total memory: 93585408 free memory: 28937584 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 10000 total memory: 93257728 free memory: 23353536 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Done so far: 11000 total memory: 93257728 free memory: 29487976 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>dan@scapps1:~/workspace/bigHeap$ </span></p>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">My second experiment was designed to confirm the book&#8217;s claim that a client program can operate on an object graph that is too big for the client&#8217;s heap. To test this I used a program that iterates over all of the objects in the HashMap created by the program I used for the first experiment. With a 19 megabyte heap the program successfully reads all of the objects in the HashMap, the actual size of which is on the order of 33 megabytes:</p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>dan@scapps1:~/workspace/bigHeap$ dso-java.sh -Xms19m -Xmx19m -classpath ./bin bigHeap.CountEm </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Starting BootJarTool&#8230; </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span><span style="font-style: normal;"><span style="text-decoration: none;">2009-06-01 00:22:37,684 INFO &#8211; Terracotta 3.0.0, as of 20090409-180411 (Revision 12431 by cruise@su10mo5 from 3.0) </span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:22:38,010 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/bigHeap/tc-config.xml&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Starting Terracotta client&#8230; </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:22:39,880 INFO &#8211; Terracotta 3.0.0, as of 20090409-180411 (Revision 12431 by cruise@su10mo5 from 3.0) </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:22:40,204 INFO &#8211; Configuration loaded from the file at &#8216;/home/dan/workspace/bigHeap/tc-config.xml&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:22:40,334 INFO &#8211; Log file: &#8216;/home/dan/workspace/bigHeap/terracotta/client-logs/terracotta-client.log&#8217;. </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>2009-06-01 00:22:42,349 INFO &#8211; Connection successfully established to server at 192.168.1.20:9510 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left"><span>Found: 11010 </span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span><span style="font-style: normal;"><span style="text-decoration: none;">dan@scapps1:~/workspace/bigHeap</span></span></span><span style="font-style: normal;"><span style="text-decoration: none;">$ </span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; text-decoration: none;" align="left">These simple experiments demonstrate that Terracotta&#8217;s virtual heap can be used to allow client programs to manage datasets that are too large for their physical heaps. The virtual heap is just one of Terracotta&#8217;s distinctive and powerful features. I&#8217;ll examine others in subsequent posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=74</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Even Briefer Look at Distributed Transactions in GigaSpaces</title>
		<link>http://blog.scapps.co.uk/?p=63</link>
		<comments>http://blog.scapps.co.uk/?p=63#comments</comments>
		<pubDate>Mon, 25 May 2009 07:39:57 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[GigaSpaces]]></category>
		<category><![CDATA[distributed]]></category>
		<category><![CDATA[transactions]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=63</guid>
		<description><![CDATA[A couple of weeks ago I posted a quick example and explanation of a GigaSpaces local transaction.  You can find the post here and get the code here. In today&#8217;s short post I will extend that example to use a distributed transaction.  We&#8217;ll do this in two steps: first we&#8217;ll break the example; then we&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I posted a quick example and explanation of a GigaSpaces local transaction.  You can find the post <a href="http://blog.scapps.co.uk/?p=47" target="_blank">here</a> and get the code <a href="http://blog.scapps.co.uk/wp-content/uploads/2009/05/GSLocalTransSrc.zip" target="_blank">here</a>.</p>
<p>In today&#8217;s short post I will extend that example to use a distributed transaction.  We&#8217;ll do this in two steps: first we&#8217;ll break the example; then we&#8217;ll fix it.</p>
<p>As a reminder, a GigaSpaces distributed transaction is any transaction that operates on more than one primary space.  In the example code, our client program executed a local transaction when it wrote two instances of TestClass to a single instance remote space.</p>
<p>In that example routing was not a concern because we created the space as unpartitioned, and we did not declare a space routing field. Behind the scenes, however, GigaSpaces selected one (the id field) for us.  You can check this on the Space Browser tab by expanding the GSSimpleTranExample space node, clicking on &#8220;Classes&#8221;, then clicking on &#8220;TestClass&#8221;.  The name of Routing Filed will appear on the Classes Info tab just above the table showing the fields (only one in our case) in the class.</p>
<p>Now drop the space using Undeploy Application on the Cluster Runtime tab.  Then recreate it as a partitioned space with two partitions and no backups.  Rerun the client application, and it will fail with this error message:</p>
<p style="padding-left: 30px;">Exception in thread &#8220;main&#8221; org.openspaces.core.TransactionDataAccessException: Invalid operation &#8211; local transaction spans over multiple spaces &#8211; [GSSimpleTranExample_container2:GSSimpleTranExample, GSSimpleTranExample_container1:GSSimpleTranExample] !<br />
You might be using hash based load balancing (partitioned schema) while writing data into multiple spaces and not into a single node.<br />
Please Use Jini Transaction manager with your operations.<br />
; nested exception is net.jini.core.transaction.TransactionException: Invalid operation &#8211; local transaction spans over multiple spaces &#8211; [GSSimpleTranExample_container2:GSSimpleTranExample, GSSimpleTranExample_container1:GSSimpleTranExample] !<br />
You might be using hash based load balancing (partitioned schema) while writing data into multiple spaces and not into a single node.<br />
Please Use Jini Transaction manager with your operations.</p>
<p>The reason is that GigaSpaces attempted to route each of the two writes to  different partitions, which turned our local transaction into a distributed transaction.  Because we configured the application with a local transaction manager, the transaction fails.</p>
<p>To fix the application we need to specify a distributed transaction manager instead of a local one.  Here&#8217;s how:</p>
<p>Find the line in the Spring application context file, <span style="font-family: Arial,sans-serif;"><span style="font-size: small;">GSSimpleTranExample.xml</span></span>, in which we specify a transaction manager:</p>
<p>&lt;!&#8211; 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	&#8211;&gt;<span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:local-tx-manager</span><span style="color: #000000;"> </span><span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;">“</span><span style="color: #2a00ff;"><em>transactionManager” </em></span><span style="color: #7f007f;">space</span><span style="color: #000000;">=</span><span style="color: #2a00ff;">“</span><span style="color: #2a00ff;"><em>gSSimpleTranExample”</em></span><span style="color: #008080;">/&gt;</span></span></span></p>
<p>and replace it with a line that looks like this:</p>
<p style="margin-bottom: 0cm;" align="left">&lt;!&#8211; 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	&#8211;&gt;</p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:distributed-tx-manager</span><span style="color: #008080;"> </span><span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;transactionManager&#8221; </em></span><span style="color: #008080;">/&gt;</span></span></span></p>
<p>Note that the distributed transaction manager, unlike a local transaction manager, is not associated with a particular space.</p>
<p>Now run the client application.  This time it should work.  You can confirm the transactional behaviour using the techniques described in the earlier post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=63</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>DICE Paper Ready at Long Last</title>
		<link>http://blog.scapps.co.uk/?p=59</link>
		<comments>http://blog.scapps.co.uk/?p=59#comments</comments>
		<pubDate>Thu, 21 May 2009 09:00:47 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[GigaSpaces]]></category>
		<category><![CDATA[Terracotta]]></category>
		<category><![CDATA[What I'm Working On]]></category>
		<category><![CDATA[DICE]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=59</guid>
		<description><![CDATA[I&#8217;ve mentioned my DICE study &#8211; a comparison of eight different solutions to a simple distributed computing problem using GigaSpaces and Terracotta &#8211; in several posts.  It is finally available for download.  If you want to take a look, please follow the link to the scapps website.  Access to the paper is quick and easy.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve mentioned my DICE study &#8211; a comparison of eight different solutions to a simple distributed computing problem using GigaSpaces and Terracotta &#8211; in several posts.  It is finally available for download.  If you want to take a look, please follow the link to the <em><strong><a href="http://www.scapps.co.uk" target="_blank">scapps</a> </strong></em>website.  Access to the paper is quick and easy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=59</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Brief Look at Local Transactions in GigaSpaces</title>
		<link>http://blog.scapps.co.uk/?p=47</link>
		<comments>http://blog.scapps.co.uk/?p=47#comments</comments>
		<pubDate>Tue, 12 May 2009 07:00:27 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[GigaSpaces]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[transactions]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=47</guid>
		<description><![CDATA[A quick look at how to implement a local transaction with GigaSpaces, and how to confirm that that is is working.]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left"><span style="font-size: small;"><span style="text-decoration: underline;"><span style="font-family: Arial,sans-serif;">Introduction</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">One way to think about GigaSpaces<a class="sdfootnoteanc" name="sdfootnote1anc" href="#sdfootnote1sym"><sup>1</sup></a> is as a sort of database management system for maintaining and accessing data spread across a set of caches.  Of course this view ignores many important capabilities of the GigaSpaces framework, but it is a useful perspective for considering GigaSpaces&#8217; transactional features.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">GigaSpaces offers transactional control over access to data in its spaces.  When the right combinations of API features are employed, data operations assume ACID characteristics.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">As a reminder, ACID is an acronym standing for “atomic, consistent, isolated and durable”.  The term refers to the behaviour that is generally expected from transactional systems.  Quoting W<em>ikipedia</em>: </span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-weight: normal;" align="left">
<ul>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><em>Atomicity: 	Either all the tasks in a transaction must be done, or none of them. 	The transaction must be completed, or else it must be undone (rolled 	back).</em></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><em>Consistency: 	Every transaction must preserve the integrity constraints — the 	declared consistency rules — of the database. It cannot place the 	data in a contradictory state.</em></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><em>Isolation: 	Two simultaneous transactions cannot interfere with one another. 	Intermediate results within a transaction are not visible to other 	transactions.</em></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><em>Durability: 	Completed transactions cannot be aborted later or their results 	discarded. They must persist through (for instance) restarts of the 	DBMS after crashes</em></span></span></p>
</li>
</ul>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">It is important to understand that GigaSpaces transactions govern only the state of data in the spaces managed by GigaSpaces.  Unlike the transactional support provided by heap-oriented products such as Terracotta and Kabira, GigaSpaces transactions do not provide guarantees concerning access to or the state of heap memory in a GigaSpaces application.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="text-decoration: underline;">Lineage</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">GigaSpaces&#8217; transaction support derives from three sources:</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="font-weight: normal;">1. Jini – At its core, GigaSpaces is an implementation of the JavaSpaces specification, which is a component of the Jini specification.  Jini was designed to allow heterogeneous software and hardware devices to interact.  The Jini specification (and reference implementation) include a facility for Jini-compliant devices to participate in distributed transactions.  GigaSpaces has inherited and extended this capability. </span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">2. JTA (Java Transaction API) – Jini provides the ability to orchestrate transactions among Jini-compliant participants such as JavaSpaces. Sometimes, however, it may be necessary to engage in a transaction both participants that are Jini-compliant and participants that do are not Jini-compliant.  For example, a GigaSpaces application might need to remove a data entry from a space and insert a corresponding row into a table in an RDBMS.  Most RDBMSs support a distributed transaction protocol called XA that allows them to participate in transactions with otherwise independent participants.  Using JTA, GigaSpaces can participate in XA distributed transactions.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">3. Spring – The Spring framework provides an abstraction of transaction management services and constructs.  GigaSpaces has embraced this abstraction and uses it as the façade for its own transaction support. </span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="font-weight: normal;">To this mix GigaSpaces adds support for </span><em><span style="font-weight: normal;">local</span></em><span style="font-weight: normal;"> transactions, meaning transactions that involve only one instance of one space.</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="text-decoration: underline;">Transaction Control</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Mirroring Spring&#8217;s capabilities, GigaSpaces offers two modes of transaction control, <em>programmatic</em> and <em>declarative</em>.   With programmatic transaction control, the programmer uses API calls to configure, start, commit and abort transactions.  With declarative transaction control, the programmer includes directives about where and how transactional behaviour should be applied.  These directives are interpreted by Spring and translated into transactional control statements that are woven into the application at runtime.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Spring declarative transaction control itself takes two forms, both of which are supported by GigaSpaces.  First, it can be configured using a pointcut specification typical of aspect-oriented implementations.  Second, methods can be annotated to indicate that they should (or should not) be executed within transactions.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="text-decoration: underline;">A Simple Example</span></span></span></p>
<p style="font-weight: normal;" align="left">
<address class="western"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="font-weight: normal;">Get the source code for this example <a href="../wp-content/uploads/2009/05/GSLocalTransSrc.zip" target="_blank">here</a>.</span></span></span></address>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Here is a simple application that illustrates how to implement a local transaction with GigaSpaces using annotation-driven declarative transaction control.  The example creates two instances of a class, then writes both instances to a space within a transaction.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">There are five files:</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<ol>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">A 	spring application context file – GSSimpleTranExample.xml – that 	sets up the proxy by which the application will access the space.  	The transaction manager is defined here.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">A 	simple POJO class – TestClass.java &#8211; two instances of which will 	be written to the space under a transaction.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">A 	Java interface – ConnBeanInterface.java – that declares the 	methods that will be used to access the space.  The interface – 	implementation pattern is used because Spring works better with 	instances of interfaces than with instances of concrete classes.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">A 	Java bean – ConnBean.java &#8211; that performs the space operations.</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
</li>
<li>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">A 	Java main program – GSSimpleTranExample.java – that instantiates 	the objects to be written to the space and invokes the method to 	write them.</span></span></p>
</li>
</ol>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Let&#8217;s start by looking at the Spring application context file.  The first item of interest is an Spring namespace element that instructs Spring to apply transactional controls to methods that are annotated with @Transactional in beans that it is managing:</span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">tx:annotation-driven</span> <span style="color: #008080;">/&gt;</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">The name of a transaction manager bean can be specified as an attribute to this element.  This is the bean containing the transaction manager that will be used to manage the transactional behaviour of the annotated methods that Spring finds in the beans that it manages.  If none is specified, as in our example, a default value of “transactionManager” is assumed.</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Next is an OpenSpaces namespace element that instruct Spring to instantiate a transaction manager:</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> </span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:local-tx-manager</span><span style="color: #000000;"> </span><span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;transactionManager&#8221; </em></span><span style="color: #7f007f;">space</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gSSimpleTranExample&#8221;</em></span><span style="color: #008080;">/&gt;</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">In our case we are using GigaSpaces&#8217; local transaction manager.  This is the best choice when each  transaction will involve only a single partition of a single space.</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Notice that the transaction manager declaration contains a reference to a space.  As we will see shortly, this construct is one of two  that constitute an apparent redundancy in the OpenSpaces namespace support for transactions.</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Next we see a typical OpenSpaces namespace space declaration that tells Spring to create a an IJSpace instance:</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:space</span> <span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gSSimpleTranExample&#8221; </em></span><span style="color: #7f007f;">url</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;jini://*/*/GSSimpleTranExample&#8221;</em></span> <span style="color: #008080;">/&gt;</span></span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">There is nothing specifically transactional about it;  it is included in this discussion because the next element, which has a transactional dimension, refers to it.</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Next is an OpenSpaces declaration of a GigaSpace:</span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:giga-space</span> <span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gigaSpace&#8221;</em></span> <span style="color: #7f007f;">space</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gSSimpleTranExample&#8221;</em></span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"> <span style="color: #7f007f;">tx-manager</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;transactionManager&#8221;</em></span> <span style="color: #008080;">/&gt;</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Note that this element includes both an explicit reference to the transaction manager declared earlier, and refers to the space that was defined earlier and that also refers to the transaction manager.</span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">os-core:giga-space</span> <span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gigaSpace&#8221;</em></span> <span style="color: #7f007f;">space</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;gSSimpleTranExample&#8221;</em></span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"> <span style="color: #7f007f;">tx-manager</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;transactionManager&#8221;</em></span> <span style="color: #008080;">/&gt;</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Next we specify our application bean that will perform the space operations:</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">bean</span><span style="color: #000000;"> </span><span style="color: #7f007f;">id</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;connBean&#8221;</em></span><span style="color: #000000;"> </span><span style="color: #7f007f;">class</span><span style="color: #000000;">=</span><span style="color: #2a00ff;"><em>&#8220;ConnBean&#8221;</em></span><span style="color: #000000;"> </span><span style="color: #008080;">/&gt;</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Spring will instantiate this bean and manage its lifecycle. </span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">We also include the OpenSpaces GigaSpace context element:</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"><span style="font-weight: normal;"> </span></span><span style="color: #008080;"><span style="font-weight: normal;">&lt;</span></span><span style="color: #3f7f7f;"><span style="font-weight: normal;">os-core:giga-space-context</span></span><span style="font-weight: normal;"> </span><span style="color: #008080;"><span style="font-weight: normal;">/&gt;</span></span></span></span></span></p>
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">so that Spring will assign the GigaSpace bean declared in the context file to a variable of type GigaSpace that is annotated with the @GigaSpaceContext annotation in our ConnBean instance.</span></span></span></p>
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">The TestClass is not transaction-aware, and is not described further.</span></span></span></p>
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="background: transparent none repeat scroll 0% 0%; margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">The ConnBeanInterface declares the method that will be implemented in ConnBean:</span></span></span></p>
<p style="background: transparent none repeat scroll 0% 0%; margin-left: 2.5cm; margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #7f0055;"><strong>public</strong></span><span style="color: #000000;"><span style="font-weight: normal;"> </span></span><span style="color: #7f0055;"><strong>interface</strong></span><span style="color: #000000;"><span style="font-weight: normal;"> ConnBeanInterface {</span></span></span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>public</strong></span><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>void</strong></span><span style="color: #000000;"> writeTwoObjects(TestClass tCI1, TestClass tCI2);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> }<span style="color: #000000;"><span style="font-family: Arundina Sans,sans-serif;"><span style="font-weight: normal;"> </span></span></span></span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Note that, although it is not transaction-aware, it could have been, as we have the option of annotating the interface class or its methods to be transactional.</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">The implementation of:</span></span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" lang="en-US" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; font-weight: normal;" lang="en-US" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #7f0055;"><strong>public</strong></span><span style="color: #7f0055;"><strong> </strong></span><span style="color: #7f0055;"><strong>void</strong></span> writeTwoObjects(TestClass tCI1, TestClass tCI2) {</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">in our ConnBean class is transactional:</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #646464;">@Transactional</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>public</strong></span><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>void</strong></span><span style="color: #000000;"> writeTwoObjects(TestClass tCI1, TestClass tCI2) {</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #0000c0;">gigaSpace</span><span style="color: #000000;">.write(tCI1);</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #0000c0;">gigaSpace</span><span style="color: #000000;">.write(tCI2);</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> }</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">The @Transactional annotation tells Spring to wrap transactional controls around this method.</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">From our main application class, here is the code that creates two instances of TestClass, then invokes the ConnBean method that will write them to the space under a transaction:</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="font-weight: normal;"> TestClass tCI1 = </span><span style="color: #7f0055;"><strong>new</strong></span><span style="font-weight: normal;"> TestClass(0);</span></span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> TestClass tCI2 = </span><span style="color: #7f0055;"><strong>new</strong></span><span style="color: #000000;"> TestClass(1);</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #0000c0;"><em>connBean</em></span><span style="color: #000000;">.writeTwoObjects(tCI1, tCI2);</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="color: #000000;"><span style="text-decoration: underline;"><span style="font-weight: normal;">Running the Example</span></span></span></span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="color: #000000;"><span style="font-weight: normal;">Before running this example, create an unpartitioned space called </span></span><span style="color: #000000;"><em><span style="font-weight: normal;">GSSimpleTranExample. </span></em></span></span></span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">When you run the example pass the path and name of the spring application context file as a command line argument.</span></span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">It it runs successfully the program will produce the following output:</span></span></span></p>
<p style="margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left">
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;">Done with my work.  About to exit.</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm; font-style: normal; font-weight: normal;" align="left">
<p style="margin-bottom: 0cm; font-weight: normal;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="text-decoration: underline;">Proving the Transactional Behaviour</span></span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal; text-decoration: none;" align="left"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Here are a few techniques that can be used to explore the transactional behaviour in this example:</span></span></span></p>
<p style="margin-bottom: 0cm; font-weight: normal; text-decoration: none;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="color: #000000;"><span style="text-decoration: none;"><span style="font-weight: normal;">1. Extend the duration of the transaction and inspect it in the GigaSpaces GUI Space Browser while it is in progress. You can extend the duration of the transaction by modifying the ConnBean class as follows:</span></span></span></span></span></p>
<ol>
<p style="margin-bottom: 0cm;" align="left"><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Arial,sans-serif;"><span style="text-decoration: none;"><span style="font-weight: normal;"><br />
</span></span></span></span><span style="color: #000000;"><span style="font-family: Arundina Sans,sans-serif;"><span style="text-decoration: none;"><span style="font-weight: normal;"><br />
</span></span></span></span><span style="color: #000000;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;"> </span></span></span></span><span style="color: #7f0055;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><strong>int</strong></span></span></span><span style="color: #000000;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;"> </span></span></span></span><span style="color: #0000c0;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;">sleepLength</span></span></span></span><span style="color: #000000;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;"> = 10000;</span></span></span></span></span></ol>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> </span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #999999;">@Transactional</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #999999;"><span style="font-family: Monospace;"><span style="font-size: small;"> <strong>public</strong> <strong>void</strong> writeTwoObjects(TestClass tCI1, TestClass tCI2) {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #999999;"><span style="font-family: Monospace;"><span style="font-size: small;"> gigaSpace.write(tCI1);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #999999;"><span style="font-family: Monospace;"><span style="font-size: small;"> gigaSpace.write(tCI2);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>try</strong></span><span style="color: #000000;"> {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> Thread.</span><span style="color: #000000;"><em>sleep</em></span><span style="color: #000000;">(</span><span style="color: #0000c0;">sleepLength</span><span style="color: #000000;">);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> } </span><span style="color: #7f0055;"><strong>catch</strong></span><span style="color: #000000;"> (Exception e) {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #3f7f5f;">// </span><span style="color: #7f9fbf;"><strong>TODO</strong></span><span style="color: #3f7f5f;"> Auto-generated catch block</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> e.printStackTrace();</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="font-size: small;"> }</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Monospace;"> </span></span><span style="color: #c0c0c0;"><span style="font-family: Monospace;">}</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;"><span style="color: #000000;"><span style="text-decoration: none;"><span style="font-weight: normal;">sleepLength is specified in milliseconds.  Set it to whatever value is convenient for you.  Then run the application, and look at the list of transactions. </span></span></span><span style="color: #000000;"><span style="text-decoration: none;"><span style="font-weight: normal;">Note that the transaction type is “Local” because we declared a local transaction manager in the application context file.  Also notice that two objects are locked by this transaction.  These are the two objects that are being inserted.<br />
</span></span></span></span></span></p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">2. Try to query the locked objects using the Space Browser and observe that they cannot be read while the transaction is in progress.  To do this, start by removing any instances of TestClass from the space.  Set the value of sleepLength to a long enough duration (perhaps 30 seconds) that you will have time to execute a query against the space while the transaction is in progress. Run the program.  Then select the TestClass class in the space browser and execute a query.  The result set will be empty.</span></span></p>
<ol>
<p style="margin-bottom: 0cm;" align="left">
</ol>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">As you are preparing to run the query you will notice that the instance count for the TestClass class is two, not zero. This is because the method that is used by the GUI to inspect the space has access to locked objects and includes them in the count value it returns.  The objects themselves, however, are not visible until the transaction commits.</span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">3. Force the transaction to roll back, and observe that the space is left empty.  To force a roll-back, raise an exception in the WriteTwoObjects() method as follows:</span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<ol>
<p style="margin-bottom: 0cm;" align="left"><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;"> </span></span></span></span><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><strong>int</strong></span></span></span><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="text-decoration: none;"><span style="font-weight: normal;"> sleepLength = 10000;</span></span></span></span></span></p>
</ol>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> </span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> @Transactional</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> <strong>public</strong> <strong>void</strong> writeTwoObjects(TestClass tCI1, TestClass tCI2) {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> gigaSpace.write(tCI1);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> gigaSpace.write(tCI2);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> <strong>try</strong> {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> Thread.<em>sleep</em>(sleepLength);</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> } <strong>catch</strong> (Exception e) {</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> // <strong>TODO</strong> Auto-generated catch block</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> e.printStackTrace();</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> }</span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"><span style="color: #000000;"> </span><span style="color: #7f0055;"><strong>throw</strong></span><span style="color: #000000;"> (</span><span style="color: #7f0055;"><strong>new</strong></span><span style="color: #000000;"> RuntimeException());</span></span></span></span></p>
<p style="margin-left: 1.25cm; margin-bottom: 0cm;" align="left"><span style="color: #c0c0c0;"><span style="font-family: Monospace;"><span style="font-size: small;"> }</span></span></span></p>
<p style="margin-bottom: 0cm;" align="left">
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><span style="font-family: Arial,sans-serif;"><span style="font-size: small;">Again, start by removing any instances of TestClass from the space.  Now when you run the application you see the transaction in progress and the TestClass instance count will go to two.  At the end of the period specified by sleepLength, the transaction will abort and the instance count will revert to zero.</span></span></p>
<div id="sdfootnote1">
<p class="sdfootnote"><span style="font-size: xx-small;"><a class="sdfootnotesym" name="sdfootnote1sym" href="#sdfootnote1anc">1</a>GigaSpaces 	technology is spread across two code bases, GigaSpaces and 	OpenSpaces.  This paper often refers to all of the technology 	indiscriminately as “GigaSpaces”.</span></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=47</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Cloud Computing and Competitive Positioning</title>
		<link>http://blog.scapps.co.uk/?p=39</link>
		<comments>http://blog.scapps.co.uk/?p=39#comments</comments>
		<pubDate>Sun, 10 May 2009 10:56:06 +0000</pubDate>
		<dc:creator>subuta</dc:creator>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://blog.scapps.co.uk/?p=39</guid>
		<description><![CDATA[Thinking through the implications of cloud computing and complementary application strategies is a worthwhile exercise for any IT executive.]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm; line-height: 150%;">(Recently posted on CIO.com)</p>
<p style="margin-bottom: 0cm; line-height: 150%;">To understand the implications of cloud computing on your organization&#8217;s competitive position, it is helpful to think about the cloud proposition from two perspectives: cost and capabilities.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">Recently a contributor to these pages, citing a McKinsey &amp; Co. report, posited  that external  clouds do not provide cost advantages over  internal data centres for organizations with scale.  Let&#8217;s assume that this is true.  We can infer, at least as a hypothetically, that external clouds do provide cost advantages for smaller organizations over the in-house alternative.  So, on a relative basis, a small organization that successfully exploits the potential cost savings offered by external clouds will improve its competitive position versus a competitor that is already exploiting its scale effectively and to which external clouds can provide no incremental cost advantage.  The implication for CIOs at sub-scale operations is that they should examine the business case for migrating to external clouds as a means of improving their organizations&#8217; competitive positions.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">For their counterparts at larger organizations, the potential for eroding advantage means that they need to find ways to preserve or extend the cost advantages that their scale provides.  Two possible approaches, not mutually exclusive, present themselves.  One is to challenge their hardware and infrastructure software vendors to adjust their pricing  so that large customer organizations can defend their current cost advantages against the threat posed by the new, alternative business model which seems to favour smaller organizations on a relative basis.  The other is to bring cloud managements technologies and techniques into their own data centres, seeking to identify and exploit whatever inherent efficiency advantages cloud providers may enjoy without paying those providers the profit margins on which their businesses operate.  Presumably any IT organization with substantial scale is already well down this path, at least with regard to host virtualization.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">The sliding relationship between internal and external infrastructure costs as a function of scale is likely to have a slight but measurable impact on the relative competitive positions of smaller and larger IT    organizations.  The potential impact of changes in relative capabilities between cloud adopters and no-adopters is much more significant.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">From an application perspective, a cloud (internal or external) is the ideal setting for horizontally scaling applications.  The ability to deploy incremental processing power on demand and at low incremental cost is the perfect compliment to scalable application architectures.  External clouds offer small or start-up organizations the ability to deploy applications with much greater actual or potential capacity than they could otherwise afford.  Small or start-up organizations that perceive and capitalize on this potential can quickly improve their relative positioning with regard to competitors.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">The ability of a newer or smaller player to punch well above its weight in terms of application capacity can neutralize a traditional advantage of scale players, transforming start-ups or small competitors into significant adversaries.  Of course, exploiting this potential advantage requires that these smaller organizations adopt newer application architectures that are designed for horizontal scalability, something that larger and better established competitors may be less inclined to do.  For newer, smaller or more agile players, adopting scalable application architectures may be both easier (because they are less prone to organizational inertia) and more of a strategic necessity.  The risk to better established and more complacent organizations is that these upstart competitors will not only challenge the larger organizations&#8217; competitive positions in the short term through clever use of complimentary application and infrastructure strategies, but that they will also develop a more enduing strategic advantage through there embrace of newer application paradigms.</p>
<p style="margin-bottom: 0cm; line-height: 150%;">Digesting and understanding the possible implications of the emergence of external cloud services on competitive position is difficult due to the newness of these services and fog of hype that envelops the topic of cloud computing.  Clues are beginning to emerge, however, as to how this new way of acquiring and managing technical infrastructure may impact organizations differently depending on size,  competitive position, and rates of adoption of newer application architectures.  Thinking through these issues and developing a view on their potential competitive impact is a worthwhile exercise for any IT executive.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scapps.co.uk/?feed=rss2&#038;p=39</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
