<?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>Rob Tiffany &#187; Sync</title>
	<atom:link href="http://robtiffany.com/category/sync/feed/" rel="self" type="application/rss+xml" />
	<link>http://robtiffany.com</link>
	<description>Author, Mobility Strategist at Microsoft, Speaker, Advisor, Technology Executive, Former Navy Submariner</description>
	<lastBuildDate>Wed, 16 May 2012 01:19:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Simple Mobile Sync with SQL Server 2012 and SQL Server Compact: Episode III</title>
		<link>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/</link>
		<comments>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 18:08:50 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=1758</guid>
		<description><![CDATA[Back in my first article, I showed you where to find Microsoft&#8217;s latest updates to the SQLCE and RDA technologies so you can begin synchronizing data with the new SQL Server 2012 (Denali) database.  Just imagine, you now have mobile &#8230; <a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="Episode I" href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/" target="_blank">Back in my first article</a>, I showed you where to find Microsoft&#8217;s latest updates to the SQLCE and RDA technologies so you can begin synchronizing data with the new <em><strong>SQL Server 2012</strong></em> (Denali) database.  Just imagine, you now have mobile sync components that give you the flexibility to to work with SQL Server 7, 2000, 2005, 2008, and 2012 from your devices.  I&#8217;d say you have both your legacy and state-of-the-art bases covered.  <a title="Episode II" href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/" target="_blank">In the second article </a>you built both the server and client databases so now you&#8217;re ready to sync some data.</p>
<p>As I may have mentioned before, Remote Data Access (RDA) is the fastest and easiest way for your mobile devices to synchronize data with SQL Server - and then take it offline in SQL Server Compact.  It works on the simple premise of pulling and pushing data to and from SQL Server via the Server Agent which is running on the middle-tier IIS application server.  The Server Agent is able to communicate with SQL Server via an OLEDB connection string which is passed to it from your device application code:</p>
<p>string rdaConnection = @&#8221;Provider=SQLOLEDB;&#8221; +</p>
<p style="padding-left: 180px;">&#8220;Data Source=Machinename\\SQLExpress;&#8221; +</p>
<p style="padding-left: 180px;">&#8220;Initial Catalog = ContosoBottling;&#8221; +</p>
<p style="padding-left: 180px;"><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;">&#8220;User Id = sa;&#8221; +</span></span></p>
<p style="padding-left: 180px;">&#8220;Password = P@ssw0rd;&#8221;;</p>
<p>You&#8217;ll use this connection string over and over whether your pulling or pushing data so keep it handy.  Data is retrieved on a table-by-table basis using the Pull method of the SqlCeRemoteDataAccess object.  You would put the example code below in a method to retrieve a list of Distribution Centers from SQL Server:</p>
<p>using (SqlCeRemoteDataAccess rda = new SqlCeRemoteDataAccess())</p>
<p>{</p>
<p style="padding-left: 30px;">rda.InternetUrl = &#8220;http://localhost/rda/sqlcesa35.dll&#8221;;</p>
<p style="padding-left: 30px;">rda.LocalConnectionString = &#8220;Data Source=ContosoBottling.sdf&#8221;;</p>
<p style="padding-left: 30px;">//Drop Table</p>
<p style="padding-left: 30px;">DropTable(&#8220;DistributionCenters&#8221;, rda.LocalConnectionString);</p>
<p style="padding-left: 30px;">//Pull Table</p>
<p style="padding-left: 30px;">rda.Pull(&#8220;DistributionCenters&#8221;,</p>
<p style="padding-left: 90px;">&#8220;SELECT DistributionCenterId, Name FROM DistributionCenters&#8221;,</p>
<p style="padding-left: 90px;">rdaConnection,</p>
<p style="padding-left: 90px;">RdaTrackOption.TrackingOnWithIndexes,</p>
<p style="padding-left: 90px;">&#8220;ErrorTable&#8221;);</p>
<p>}</p>
<p>Notice that the mobile device connects to the Server Agent on IIS by pointing to it via a URL.  After that, you assign a connection string that points to the local path of your SQLCE database.  For now, I want you to ignore the DropTable method, because I&#8217;ll cover it in a sec.  The Pull method is where the magic happens.  In the first parameter, you pass in the name of the local table you want to create as an argument.  This typically matches the name of the table you&#8217;re retrieving from SQL Server.  In the second parameter, you pass a standard SQL statement or call to stored procedure.  This is how you filter the data you want to download to the device.  I don&#8217;t want to see any SELECT *&#8217;s and I do expect to see appropriate use of the WHERE clause to reduce the amount of data downloaded.  Remember, this filtering allows you download lookup tables that apply to everyone, as well as tables with data that uniquely pertain to a specific user.  In the next parameter you pass in the OLEDB connection string I displayed at the beginning of the article.  The following parameter is where you decide if you want SQLCE to track changes or not, as well as whether to create the same indexes found on the server.  Indexes are typically always a good thing except for very small tables.  Download-only data won&#8217;t need change-tracking but your transactional stuff will.  This amazing feature allows offline users of your app to keep working in the absence of a network connection.  In the last parameter you specify the name of a table to auto-create to track any sync errors that may arise.</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/serverexplorer/" rel="attachment wp-att-1787"><img class="alignleft size-full wp-image-1787" title="ServerExplorer" src="http://robtiffany.com/wp-content/uploads/2012/04/ServerExplorer.png" alt="Server Explorer" width="243" height="205" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>After executing this code, I connected to the new SQLCE ContosoBottling bottling database on my Windows laptop using the Server Explorer in Visual Studio as shown above.  You can see that the ErrorTable and DistributionCenters tables were created locally.</p>
<p>So now let&#8217;s talk about that DropTable method.  RDA works on the premise of downloading complete table snapshots.  Unlike Merge Replication that downloads incremental changes from SQL Server, RDA re-downloads the entire table in order to make SQLCE aware of any server changes.  The catch is that you have to drop an existing local table before downloading an updated version from SQL Server.  Here&#8217;s how you do it:</p>
<p>private void DropTable(string tableName, string connectionString)</p>
<p>{</p>
<p style="padding-left: 30px;">using (SqlCeConnection cn = new SqlCeConnection(connectionString))</p>
<p style="padding-left: 30px;">{</p>
<p style="padding-left: 60px;">SqlCeCommand cmd = cn.CreateCommand();</p>
<p style="padding-left: 60px;">cmd.CommandText = String.Format(&#8220;SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = &#8216;{0}&#8217;&#8221;, tableName);</p>
<p style="padding-left: 60px;">cn.Open();</p>
<p style="padding-left: 60px;">if((int)cmd.ExecuteScalar() == 1)</p>
<p style="padding-left: 60px;">{</p>
<p style="padding-left: 90px;">cmd.CommandText = String.Format(&#8220;DROP TABLE {0}&#8221;, tableName);</p>
<p style="padding-left: 90px;">cmd.ExecuteNonQuery();</p>
<p style="padding-left: 60px;">}</p>
<p style="padding-left: 30px;">}</p>
<p>}</p>
<p>You can see that I use SqlCeConnection and SqlCeCommand objects in order to query the INFORMATION_SCHEMA.TABLES database object.  If the return value of the query is 1, then you know that a table already exists.  This result leads you to execute a DROP TABLE statement so that the existing table is gone before the new one is downloaded.</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/localquery/" rel="attachment wp-att-1792"><img class="alignleft size-full wp-image-1792" title="LocalQuery" src="http://robtiffany.com/wp-content/uploads/2012/04/LocalQuery.png" alt="Local Query" width="603" height="206" /></a></p>
<p>&nbsp;</p>
<p>Right-clicking on DistributionCenters and selecting Show Table Data reveals that the Seattle and Redmond distribution centers and their associated uniqueidentifiers were downloaded to SQLCE from SQL Server 2012.</p>
<p>Right about now, I know you&#8217;re thinking that this whole process of dropping a table and re-downloading a new one in order to keep a mobile database up to date sounds wasteful.  I get it.  I also get all the heavyweight processes that are required by Merge Replication to figure out server changes for each device that synchronizes with SQL Server.  You have to weigh your options.  For instance, in boosting Merge Replication performance and scalability, one of the keys to success is maintaining a low Subscription Expiration value.  This value determines how long a mobile user can go without synchronizing her data before her subscription expires, which requires her to re-download an entire database from scratch.  Keeping a low value ensures that SQL Server doesn&#8217;t track too much performance-degrading metadata.  It also means that users might have to synchronize more frequently than business rules dictate.  The great thing about RDA is that the notion of a subscription doesn&#8217;t exist since it downloads table snapshots to keep mobile clients up to date.  This means users can download data to their devices and remain disconnected for an indefinite amount of time while capturing new data out in the field.  No expiration or degraded performance on SQL Server 2012.  This leads to infinitely greater scalability for your system.</p>
<p>In the most common mobile scenarios I see in business, laptops/devices download the data needed to perform work for a given day via Wi-Fi or cradled Ethernet.  Unless each of your downloaded tables are 100+ MB a piece, this shouldn&#8217;t be a big deal at these types of network speeds.  Most organizations roll their own web services to do the same thing and they don&#8217;t bat an eye at the amount of data they have to re-download with each web method call.  Heck, most companies I work with allow their devices to take all night to download the data needed for the next morning.</p>
<p>So after a user has spent some time in the field capturing new data or changing/deleting existing data, it&#8217;s time to push those tracked changes back up to SQL Server 2012.  This is the simplest code of all:</p>
<p>SqlCeRemoteDataAccess rda = new SqlCeRemoteDataAccess();</p>
<p>rda.InternetUrl = &#8220;http://localhost/rda/sqlcesa35.dll&#8221;;</p>
<p>rda.LocalConnectionString = &#8220;Data Source=ContosoBottling.sdf&#8221;;</p>
<p>rda.Push(&#8220;DistributionCenters&#8221;, rdaConnection, RdaBatchOption.BatchingOn);</p>
<p>For each table that you tracked changes for, you need to use the SqlCeRemoteDataAccess object and the Push method.  The first parameter should look familiar since it&#8217;s the name of the tracked table that you had previously Pulled.  The second parameter is the same OLEDB connection string we used in the Pull method.  The last one allows you to specify batching of uploads.  This feature gives you the transactional, all-or-nothing functionality of a message queue.  If any of the table data uploads fail, the whole transaction is rolled back.  This is a great feature to ensure data integrity.</p>
<p>Before you run this code, I want you to go back to the local SQLCE query result from the Server Explorer in Visual Studio and change the Distribution Center Name column from Redmond to Bellevue.  I have to prove that this great change tracking feature actually works after all.  Once you&#8217;ve made the change and hit the tab key to save it, go ahead and run your Push code.  If everything works as expected, the local change you made should be pushed up to SQL Server.  We need some proof, so open up SQL Server Managment Studio:</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/objectexplorer/" rel="attachment wp-att-1799"><img class="alignleft size-full wp-image-1799" title="ObjectExplorer" src="http://robtiffany.com/wp-content/uploads/2012/04/ObjectExplorer.png" alt="Object Explorer" width="755" height="248" /></a></p>
<p>&nbsp;</p>
<p>Right-clicking on dbo.DistributionCenters and clicking Select Top 1000 Rows should return the result you see in the figure above.  Happily, the local SQLCE change from Redmond to Bellevue is reflected in the result on SQL Server 2012.</p>
<p>The circle is complete.</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Mobile Sync with SQL Server 2012 and SQL Server Compact: Episode II</title>
		<link>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/</link>
		<comments>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 03:21:42 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=1683</guid>
		<description><![CDATA[In my last article, I walked you through finding, downloading, installing, and configuring SQL Server 2012 Express, SQL Server Compact 3.5 SP2 CU6, and the Sync Server Tools.  With that series of tasks completed, you&#8217;re now capable of performing data synchronization with &#8230; <a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my last article, I walked you through finding, downloading, installing, and configuring SQL Server 2012 Express, SQL Server Compact 3.5 SP2 CU6, and the <em><strong>Sync </strong></em>Server Tools.  With that series of tasks completed, you&#8217;re now capable of performing data synchronization with a mobile Windows client.</p>
<p>Open SQL Server 2012 Management Studio and connect to the local SQL Express instance.  You’ll quickly notice the new Visual Studio 2010 IDE look and feel.  Since you’re going to need a database to sync with, right-click on the Databases folder in the Object Explorer and select New Database.  Type ContosoBottling in the Database name text box and click OK.  I want you to create three simple tables for the purposes of this article:</p>
<table width="646" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="137"><strong>DistributionCenters</strong></td>
<td colspan="5" width="509"></td>
</tr>
<tr>
<td valign="top" width="137"><strong>Column</strong></td>
<td valign="top" width="93"><strong>PK</strong></td>
<td valign="top" width="113"><strong>Data Type</strong></td>
<td valign="top" width="97"><strong>Nulls</strong></td>
<td valign="top" width="102"><strong>Defaults</strong></td>
<td valign="top" width="104"><strong>RowGuid</strong></td>
</tr>
<tr>
<td valign="top" width="137">DistributionCenterId</td>
<td valign="top" width="93">Yes</td>
<td valign="top" width="113">uniqueidentifier</td>
<td valign="top" width="97">No</td>
<td valign="top" width="102">newid()</td>
<td valign="top" width="104">Yes</td>
</tr>
<tr>
<td valign="top" width="137">Name</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">nchar(20)</td>
<td valign="top" width="97">Yes</td>
<td valign="top" width="102"></td>
<td valign="top" width="104">No</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="646" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="137"><strong>Routes</strong></td>
<td colspan="5" width="509"></td>
</tr>
<tr>
<td valign="top" width="137"><strong>Column</strong></td>
<td valign="top" width="93"><strong>PK</strong></td>
<td valign="top" width="113"><strong>Data Type</strong></td>
<td valign="top" width="97"><strong>Nulls</strong></td>
<td valign="top" width="102"><strong>Defaults</strong></td>
<td valign="top" width="104"><strong>RowGuid</strong></td>
</tr>
<tr>
<td valign="top" width="137">RouteId</td>
<td valign="top" width="93">Yes</td>
<td valign="top" width="113">uniqueidentifier</td>
<td valign="top" width="97">No</td>
<td valign="top" width="102">newid()</td>
<td valign="top" width="104">Yes</td>
</tr>
<tr>
<td valign="top" width="137">DistributionCenterId</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">uniqueidentifier</td>
<td valign="top" width="97">Yes</td>
<td valign="top" width="102"></td>
<td valign="top" width="104">No</td>
</tr>
<tr>
<td valign="top" width="137">Name</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">nchar(20)</td>
<td valign="top" width="97">Yes</td>
<td valign="top" width="102"></td>
<td valign="top" width="104">No</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="640" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="112"><strong>Drivers</strong></td>
<td colspan="5" width="528"></td>
</tr>
<tr>
<td valign="top" width="112"><strong>Column</strong></td>
<td valign="top" width="93"><strong>PK</strong></td>
<td valign="top" width="113"><strong>Data Type</strong></td>
<td valign="top" width="105"><strong>Nulls</strong></td>
<td valign="top" width="108"><strong>Defaults</strong></td>
<td valign="top" width="109"><strong>RowGuid</strong></td>
</tr>
<tr>
<td valign="top" width="112">DriverId</td>
<td valign="top" width="93">Yes</td>
<td valign="top" width="113">uniqueidentifier</td>
<td valign="top" width="105">No</td>
<td valign="top" width="108">newid()</td>
<td valign="top" width="109">Yes</td>
</tr>
<tr>
<td valign="top" width="112">RouteId</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">uniqueidentifier</td>
<td valign="top" width="105">Yes</td>
<td valign="top" width="108"></td>
<td valign="top" width="109">No</td>
</tr>
<tr>
<td valign="top" width="112">FirstName</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">nchar(20)</td>
<td valign="top" width="105">Yes</td>
<td valign="top" width="108"></td>
<td valign="top" width="109">No</td>
</tr>
<tr>
<td valign="top" width="112">LastName</td>
<td valign="top" width="93"></td>
<td valign="top" width="113">nchar(20)</td>
<td valign="top" width="105">Yes</td>
<td valign="top" width="108"></td>
<td valign="top" width="109">No</td>
</tr>
</tbody>
</table>
<p>If you read my last book on Enterprise Data Replication, these tables that support the operations of a delivery driver should look familiar to you.  Since RDA doesn’t support the Identity Range feature of Merge Replication, you’ll be using GUIDs for your primary keys to ensure uniqueness.  Since the offline data capabilities of sync technologies from all vendors are based on the notion of optimistic concurrency, having a globally unique primary key that won’t collide with inserts and updates made by one or more devices is critical to success.  Now it’s time to fill these tables with some sample data to get started:</p>
<p>Right-click on DistributionCenters and select Edit Top 200 Rows.  Type Seattle for the Name in the first row and Redmond for the Name in the second row.  Allow the DistributionCenterId uniqueidentifier values to be automatically created.  It should look something like this:</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/dc/" rel="attachment wp-att-1694"><img class="alignleft size-full wp-image-1694" title="DistributionCenter" src="http://robtiffany.com/wp-content/uploads/2012/04/DC.png" alt="Distribution Center" width="364" height="115" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Now it’s time to tackle the Routes table.  Each Distribution Center will have multiple routes that it supplies products to.  Right-click on Routes and select Edit Top 200 Rows.  Like before, allow the RouteId uniqueidentifier values to be automatically created.  The eight rows of data I want you to enter should be as follows:</p>
<ol>
<li>The DistributionCenterID should equal the related Seattle value from the DistributionCenters table and the Name should equal Magnolia.</li>
<li>The DistributionCenterID should equal the related Seattle value from the DistributionCenters table and the Name should equal Ballard.</li>
<li>The DistributionCenterID should equal the related Seattle value from the DistributionCenters table and the Name should equal Fremont.</li>
<li>The DistributionCenterID should equal the related Seattle value from the DistributionCenters table and the Name should equal Wallingford.</li>
<li>The DistributionCenterID should equal the related Redmond value from the DistributionCenters table and the Name should equal Kirkland.</li>
<li>The DistributionCenterID should equal the related Redmond value from the DistributionCenters table and the Name should equal Bellevue.</li>
<li>The DistributionCenterID should equal the related Redmond value from the DistributionCenters table and the Name should equal Issaquah.</li>
<li>The DistributionCenterID should equal the related Redmond value from the DistributionCenters table and the Name should equal Sammamish.</li>
</ol>
<p>It should look something like this:</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/routes/" rel="attachment wp-att-1695"><img class="alignleft size-full wp-image-1695" title="Routes" src="http://robtiffany.com/wp-content/uploads/2012/04/routes.png" alt="Routes" width="590" height="249" /></a></p>
<p>&nbsp;</p>
<p>Last but not least, we have the Drivers.  Each of these folks will be assigned to a particular route on any given day.  Right-click on Drivers and select Edit Top 200 Rows.  For each row, allow the DriverId uniqueidentifier values to be automatically created.  I’ll just have you enter a couple of drivers for this table:</p>
<ol>
<li>The RouteId should equal the related Magnolia value from the Routes table and the FirstName should equal Dave and the LastName should equal Bottomley.</li>
<li>The RouteId should equal the related Kirkland value from the Routes table and the FirstName should equal Khalid and the LastName should equal Siddiqui.</li>
</ol>
<p>It should look something like this:</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/drivers/" rel="attachment wp-att-1702"><img class="alignleft size-full wp-image-1702" title="Drivers" src="http://robtiffany.com/wp-content/uploads/2012/04/Drivers.png" alt="Drivers" width="666" height="116" /></a></p>
<p>&nbsp;</p>
<p>Now that your sample database has some data inside, it’s time to build a sample Windows app so fire up Visual Studio 2010.  Create a Windows Forms or WPF application and call the Solution SimpleSync.  The first thing I want you to do is go to the Solution Explorer, right-click on References, and add a reference to System.Data.SqlServerCe.  To make sure you’re working with the newest bits based on Cumulative Update package 6, in the Add Reference dialog, click the Browse tab and navigate to C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Desktop\System.Data.SqlServerCe.dll.</p>
<p>With those pieces in place, it&#8217;s time to write some code.</p>
<p>Unlike Merge Replication that automatically creates a SQL Server Compact database for you during the initial sync, with RDA you&#8217;ll need to create it in code with the SqlCeEngine object.  So before your app can start synchronizing data, you&#8217;ll need to first create a database with the following code:</p>
<h6><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;">if</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;"> (!</span></span><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;">File</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;">.Exists(</span></span><span style="color: #a31515; font-family: Consolas; font-size: medium;"><span style="color: #a31515; font-family: Consolas; font-size: medium;"><span style="color: #a31515; font-family: Consolas; font-size: medium;">&#8220;ContosoBottling.sdf&#8221;</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;">))</span></span></h6>
<h6>{</h6>
<h6 style="padding-left: 30px;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;">using</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;"> (</span></span><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;">SqlCeEngine</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;"> sqlEngine = </span></span><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;"><span style="color: #0000ff; font-family: Consolas; font-size: medium;">new </span></span></span><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;"><span style="color: #2b91af; font-family: Consolas; font-size: medium;">SqlCeEngine</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;">())</span></span></h6>
<h6 style="padding-left: 30px;">{</h6>
<h6 style="padding-left: 60px;">sqlEngine.LocalConnectionString = &#8221;<span style="color: #a31515; font-family: Consolas; font-size: medium;"><span style="color: #a31515; font-family: Consolas; font-size: medium;"><span style="color: #a31515; font-family: Consolas; font-size: medium;">Data Source=ContosoBottling.sdf&#8221;</span></span></span><span style="font-family: Consolas; font-size: medium;"><span style="font-family: Consolas; font-size: medium;">;</span></span></h6>
<h6 style="padding-left: 60px;">sqlEngine.CreateDatabase();</h6>
<h6 style="padding-left: 30px;">}</h6>
<h6>}</h6>
<p>The first thing the above code does is to check and see if a SQL Server Compact database already exists.  If not, then the SqlCeEngine object is instantiated.  The LocalConnectionString property is set to the path of where you want the database to reside.  In this case, I didn&#8217;t enter a path so the database will be created in the same folder as the app&#8217;s exe.  Keep in mind that a number of other parameters can be used for this property to support password protection and encryption among others.  Next, you just call the CreateDatabase() method and that&#8217;s all there is to it.  You will now have an empty shell of a database that typically weighs in at 20 KB.</p>
<p>With a local database created, you can begin retrieving data.  In my next article I&#8217;ll discuss how to RDA filters and pulls both data and indexes, enables local change-tracking, and pushes new data and updates back to SQL Server.</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Mobile Sync with SQL Server 2012 and SQL Server Compact: Episode I</title>
		<link>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/</link>
		<comments>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 03:54:28 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=1619</guid>
		<description><![CDATA[Now that SQL Server 2012 has been released, some of you might be wondering if SQL Server Compact is capable of synchronizing with it.  With the release of Cumulative Update Package 6 for SQL Server Compact 3.5 Service Pack 2, the answer &#8230; <a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now that <strong>SQL Server 2012</strong> has been released, some of you might be wondering if <em><strong>SQL Server Compact</strong></em> is capable of synchronizing with it.  With the release of <a title="Cumulative Update Package 6" href="http://support.microsoft.com/kb/2628887" target="_blank">Cumulative Update Package 6 for SQL Server Compact 3.5 Service Pack 2</a>, the answer is a resounding yes!  Build number 3.5.8088.00 adds support for replication with<strong> SQL Server</strong> &#8220;<strong>Denali</strong>&#8221; which is pretty awesome in my book.  For those of you keeping score at home, check out Erik&#8217;s<strong> <a title="Everything SQL Server Compact" href="http://erikej.blogspot.com/" target="_blank">Everything SQL Server Compact</a> </strong>blog to see a running total of improvements to <strong>SQLCE</strong> via Cumulative Updates.  After that, click on the Cumulative Update link at the beginning of this article and head on over to the <strong>Microsoft Support</strong> page to get started.</p>
<p>At the top of the page it says <strong>Hotfix Download Available</strong> and beneath that says <a title="Hotfix Downloads" href="http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=2628887&amp;kbln=en-us" target="_blank">View and request hotfix downloads </a>so click on that.  Keep in mind that my link was defined by my U.S. English IE9 browser so the page I navigated to shows me checkboxes to download x64 Server Tools for IIS and both x86 and x64 versions for Windows.  Your experience may be different depending on where you live.  Luckily, there&#8217;s a link that says<strong> Show hotfixes for all platforms and languages</strong>.  Check the checkboxes to select your language, the Server Tools, Windows, and Windows Mobile/Embedded platforms that you&#8217;re looking for.  Afterward, type in your email address and play the Captcha game in order to have links to the bits you need sent to you.</p>
<p>The next thing you&#8217;re going to need is a copy of SQL Server 2012.  To keep things simple with this series of articles, I won&#8217;t dive into security and I decided that I&#8217;ll use my x64 Windows 7 laptop as the database server, middleware, mobile platform and use <strong>Remote Data Access (RDA)</strong> as the sync transport.  I think you&#8217;ve probably already heard enough about Merge Replication from me so I decided to mix it up a bit with my old friend RDA.  Remember, RDA does not require any configuration on SQL Server, it is not invasive to the schema of the server database, and it&#8217;s amazingly fast and scalable.  With over 650 million copies of <strong>Windows 7</strong> deployed, this is by far the most widely used, occasionally-connected mobile platform in the world, so I don&#8217;t feel bad about not writing another <strong>Windows Phone</strong> article.  <a title="SQL Server 2012 Express" href="http://www.microsoft.com/betaexperience/pd/SQLEXPCTAV2/enus/default.aspx" target="_blank">Navigate your browser to download the free SQL Server 2012 Express with Advanced Services </a>since we won&#8217;t be needing support for Replication.  You might need to navigate elsewhere if you&#8217;re not targetting U.S. English.  Sorry about that.  Once you&#8217;ve downloaded the exe, install the product and make sure you can login via SQL <strong>Server Management Studio</strong>.</p>
<p>At this point, go ahead and install the 32 and 64-bit versions of the <strong>SQL Server Compact 3.5 SP2</strong> runtimes that you downloaded as appropriate.  Remember, on a 64-bit OS, you must install both the x86 and x64 versions in order to have smooth sailing with out favorite embedded database.</p>
<p>I already have <strong>IIS</strong> installed on my x64 Windows 7 laptop so I&#8217;m in good shape to install the<strong> x64 Server Tools</strong>.  Unzip your CU 6 update and click SSCEServerTools-ENU.msi to begin the Server Tools installation.  As a refresher, you must have IIS 6 Management Compatibility enabled to make things work with IIS 7.5.  During the install make sure all the <strong>System Configuration Checks</strong> are successful, and that you select <strong>SQL Server &#8220;Denali&#8221;</strong> to synchronize with. With the Server Tools installed, I want you to create a local folder on your computer and call it <strong>SnapshotShare</strong> and <strong>Share</strong> it with <strong>Everyone</strong> to keep things simple.  It&#8217;s a little silly since RDA doesn&#8217;t use a Snaphot Share, but the installation Wizard may no let you proceed without it.</p>
<p>I know many of you have followed the screenshot-filled installation routines in my books so I&#8217;ll keep the pictures microscopic this time around.  Click <strong>Windows Start</strong>, navigate to <strong>Microsoft SQL Server Compact 3.5</strong>, and select <strong>Configure Web Synchronization Wizard</strong>.</p>
<p>Welcome to the Configure Web Synchronization Wizard | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/9/" rel="attachment wp-att-1645"><img class="alignleft size-full wp-image-1645" title="9" src="http://robtiffany.com/wp-content/uploads/2012/03/9.jpg" alt="" width="160" height="145" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Subscriber Type | Select SQL Server Compact | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/10/" rel="attachment wp-att-1646"><img class="alignleft size-full wp-image-1646" title="10" src="http://robtiffany.com/wp-content/uploads/2012/03/10.jpg" alt="" width="160" height="146" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Web Server | Create a new virtual directory | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/11/" rel="attachment wp-att-1647"><img class="alignleft size-full wp-image-1647" title="11" src="http://robtiffany.com/wp-content/uploads/2012/03/11.jpg" alt="" width="160" height="146" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Virtual Directory Information | Type RDA in the Alias textbox | Click Next | Click Yes to create a folder | Click Yes again</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/12/" rel="attachment wp-att-1648"><img class="alignleft size-full wp-image-1648" title="12" src="http://robtiffany.com/wp-content/uploads/2012/03/12.jpg" alt="" width="160" height="145" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Secure Communications | Select Do not require secure channel (SSL) | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/15/" rel="attachment wp-att-1651"><img class="alignleft size-full wp-image-1651" title="15" src="http://robtiffany.com/wp-content/uploads/2012/03/15.jpg" alt="" width="160" height="144" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Client Authentication | Select Clients will connect anonymously | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/16/" rel="attachment wp-att-1652"><img class="alignleft size-full wp-image-1652" title="16" src="http://robtiffany.com/wp-content/uploads/2012/03/16.jpg" alt="" width="160" height="147" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Anonymous Access | Default IUSR account of IIS will be used | Click Next</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/17/" rel="attachment wp-att-1653"><img class="alignleft size-full wp-image-1653" title="17" src="http://robtiffany.com/wp-content/uploads/2012/03/17.jpg" alt="" width="160" height="145" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Snapshot Share Access | Enter path to the shared folder I told you to create | Click Next | Click Yes</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/18/" rel="attachment wp-att-1654"><img class="alignleft size-full wp-image-1654" title="18" src="http://robtiffany.com/wp-content/uploads/2012/03/18.jpg" alt="" width="160" height="147" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Complete the Wizard | Verify the choices you made | Click Finish</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/20/" rel="attachment wp-att-1656"><img class="alignleft size-full wp-image-1656" title="20" src="http://robtiffany.com/wp-content/uploads/2012/03/20.jpg" alt="" width="160" height="147" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Configure Web Synchronization | You should have 9 successes | Click Close</p>
<p><a href="http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/attachment/21/" rel="attachment wp-att-1657"><img class="alignleft size-full wp-image-1657" title="21" src="http://robtiffany.com/wp-content/uploads/2012/03/21.jpg" alt="" width="160" height="145" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Congratulations!  You&#8217;re done.</p>
<p>Test your Server Tools installation using Internet Explorer and navigate to this address: <a href="http://localhost/rda/sqlcesa35.dll">http://localhost/rda/sqlcesa35.dll</a>.  Your browser should display <strong>&#8220;Microsoft SQL Server Compact Server Agent&#8221;</strong> if all went well.  Your configuration tasks are almost complete, but I need you to bring up SQL Server Management Studio to do one more thing for me.  In SQL Server, create a new login called NT AUTHORITY\IUSR  with ContosoBottling as the default database so devices can anonymously connect to IIS and SQL Server to sync.  I apologize for not having you build out a network full of servers and for not having you use Windows auth against Active Directory.  Remember, when it&#8217;s time to go to production, you&#8217;ll do this the secure way.</p>
<p>You&#8217;ve accomplished a lot by following along through this article and all the pieces are in place to create an occasionally-connected solution for yourself, your company, or your customers.  In the next article, we&#8217;ll build a sample database and start writing some code in Visual Studio 2010.</p>
<p>Stay in sync,</p>
<p>Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/simple-mobile-sync-with-sql-server-2012-and-sql-server-compact-episode-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Microsoft Sync Framework 4.0 October 2010 CTP has Arrived!</title>
		<link>http://robtiffany.com/the-microsoft-sync-framework-4-0-october-2010-ctp-has-arrived/</link>
		<comments>http://robtiffany.com/the-microsoft-sync-framework-4-0-october-2010-ctp-has-arrived/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 21:24:12 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[OData]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[Sync Framework]]></category>
		<category><![CDATA[SyncFx]]></category>
		<category><![CDATA[Windows Phone 7]]></category>

		<guid isPermaLink="false">http://robtiffany.com/sync/the-microsoft-sync-framework-4-0-october-2010-ctp-has-arrived</guid>
		<description><![CDATA[Run, don’t walk, and download the new SyncFx bits to sync your connected devices with SQL Server and SQL Azure!&#160; Below is a quick rundown of all the features from the Microsoft Download Center page: Microsoft Sync Framework 4.0 October &#8230; <a href="http://robtiffany.com/the-microsoft-sync-framework-4-0-october-2010-ctp-has-arrived/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Run, don’t walk, and <a href="http://bit.ly/a5G1p2" target="_blank">download</a> the new SyncFx bits to sync your connected devices with SQL Server and SQL Azure!&#160; Below is a quick rundown of all the features from the Microsoft Download Center page:</p>
<p><b>Microsoft Sync Framework 4.0 October 2010 CTP Overview</b>    <br />The Microsoft Sync Framework 4.0 October 2010 CTP is built on top of Sync Framework 2.1. It defines Odata + Sync, a sync protocol that makes it easy to build offline applications on any client platform capable of caching data. The CTP enables synchronization of data stored in Sql Server/Sql Azure over an open standard network format by a remote synchronization service handling all sync specific computations. Moving all synchronization logic off the client enables clients, which do not have the Sync Framework runtime installed, to cache data and participate in a synchronization topology. Earlier versions of Sync Framework required Windows systems with Sync Framework runtime installed on them as clients. This CTP allows other Microsoft platforms such as Silverlight, Windows Phone 7, and Windows Mobile and non-Microsoft platforms such as HTML5, iPhone, Android and other devices with no Sync Framework runtime installed on them as clients. The CTP release includes: </p>
<ul>
<li><b>Protocol: </b>In this release, we apply the principles of <a href="http://www.odata.org/">OData</a> to the problem of data-sync and adds synchronization semantics to the protocol format. Clients and the service use the protocol to perform synchronization, where a full synchronization is performed the first time subsequently followed by smaller incremental synchronization. The protocol is designed with the goal to make it easy to implement the client-side of the protocol and all the synchronization logic will be running on the service side. It is intended to be used to enable synchronization for a variety of sources including, but not limited to, relational databases and file systems.</li>
<li><b>Server and Client Components: </b>The release includes server components that make it easy for you to build a synchronization Web service that exposes data from SQL Server or SQL Azure via the Sync protocol. The CTP release includes client component’s that make it easy for you to build offline applications on Silverlight for desktop and Windows Phone 7 platforms.</li>
<li><b>SyncSvcUtil.exe utility: </b>The release includes a command-line tool, SyncSvcUtil.exe, which helps you with defining and developing sync services and clients.</li>
<li><b>Business Logic Extensibility on Server: </b>The release allows you to plug in to the synchronization runtime on the service and enable custom business logic configuration using SyncInterceptors.</li>
<li><b>Diagnostic Dashboard: </b>The release supports a diagnostic dashboard to diagnose the health of the deployed sync services.</li>
<li><b>Samples and Tutorials: </b>The CTP ships with samples that include a sample service exposing a ToDo list data model as a Odata + Sync service. It also ships the Silverlight, Windows Phone 7, Windows Mobile 6.5 and HTML5 clients that synchronize with the service to show you how to use the components and the protocol. The documentation for CTP contains tutorials, which walk you through creating and consuming a sync service that you can deploy to an on-premise Windows Server or Windows Azure. </li>
</ul>
<p><b>Upcoming Release Refresh in Few Weeks </b>  <br />The following features will be available in few weeks after <a href="http://www.microsoft.com/events/pdc/">PDC10</a> as a refresh to this release. We will keep you updated on this release on <a href="http://social.microsoft.com/Forums/en-US/synclab">Sync Framework forums</a> and on <a href="http://blogs.msdn.com/b/sync/">Sync Framework Blog</a>.
<ul>
<li><b>Tooling Wizard UI: </b>This adds a UI wizard on top of the command line based SyncSvcUtil utility. This wizard allows you to select tables, columns, and even rows to define a sync scope, provision/de-provision a database and generate server-side/client-side code based on the data schema that you have. This minimizes the amount of code that you have to write yourself to build sync services or offline applications.</li>
<li><b>iPhone Sample: </b>This sample shows you how to develop an offline application on iPhone/iPad with SQLite for a particular remote schema by consuming the protocol directly.</li>
</ul>
<p><b>Version Change Notice</b>    <br />In this release we decided to bump the version of all binaries to 4.0, skipping version 3.0 to keep the version number consistent across all components in the release. </p>
<p>Keep Synching!</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/the-microsoft-sync-framework-4-0-october-2010-ctp-has-arrived/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sync Framework 2.1 has Arrived!</title>
		<link>http://robtiffany.com/sync-framework-2-1-has-arrived/</link>
		<comments>http://robtiffany.com/sync-framework-2-1-has-arrived/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 20:21:43 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=286</guid>
		<description><![CDATA[With Sync Framework 2.1, you can leverage the Windows Azure Platform to extend the reach of your data to anyone that has an internet connection, without making a significant investment in the infrastructure that is typically required. <a href="http://robtiffany.com/sync-framework-2-1-has-arrived/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sync Framework 2.1 includes all the great functionality of our 2.0 release, enhanced by several exciting new features and improvements. The most exciting of these lets you synchronize data stored in SQL Server or SQL Server Compact with SQL Azure in the cloud. We’ve added top customer requests like parameter-based filtering and the ability to remove synchronization scopes and templates from a database, and of course we’ve made many performance enhancements to make synchronization faster and easier. Read on for more detail or start <a href="http://bit.ly/bsQxqo">downloading</a> now!</p>
<p><strong> </strong></p>
<p><strong>SQL Azure Synchronization </strong></p>
<p>With Sync Framework 2.1, you can leverage the Windows Azure Platform to extend the reach of your data to anyone that has an internet connection, without making a significant investment in the infrastructure that is typically required. Specifically, Sync Framework 2.1 lets you extend your existing on premises SQL Server database to the cloud and removes the need for customers and business partners to connect directly to your corporate network. After you configure your SQL Azure database for synchronization, users can take the data offline and store it in a client database, such as SQL Server Compact or SQL Server Express, so that your applications operate while disconnected and your customers can stay productive without the need for a reliable network connection. Changes made to data in the field can be synchronized back to the SQL Azure database and ultimately back to the on premises SQL Server database. Sync Framework 2.1 also includes features to interact well with the shared environment of Windows Azure and SQL Azure. These features include performance enhancements, the ability to define the maximum size of a transaction to avoid throttling, and automatic retries of a transaction if it is throttled by Windows Azure. All of this is accomplished by using the same classes you use to synchronize a SQL Server database, such as <strong>SqlSyncProvider</strong> and <strong>SqlSyncScopeProvisioning</strong>, so you can use your existing knowledge of Sync Framework to easily synchronize with SQL Azure.</p>
<p><strong> </strong></p>
<p><strong>Bulk Application of Changes </strong></p>
<p>Sync Framework 2.1 takes advantage of the table-valued parameter feature of SQL Server 2008 and SQL Azure to apply multiple inserts, updates, and deletes by using a single stored procedure call, instead of requiring a stored procedure call to apply each change. This greatly increases performance of these operations and reduces the number of round trips between client and server during change application. Bulk procedures are created by default when a SQL Server 2008 or SQL Azure database is provisioned.</p>
<p><strong> </strong></p>
<p><strong>Parameter-based Filtering </strong></p>
<p>Sync Framework 2.1 enables you to create parameter-based filters that control what data is synchronized. Parameter-based filters are particularly useful when users want to filter data based on a field that can have many different values, such as user ID or region, or a combination of two or more fields. Parameter-based filters are created in two steps. First, filter and scope templates are defined. Then, a filtered scope is created that has specific values for the filter parameters. This two-step process has the following advantages:</p>
<ul>
<li><em>Easy to set up</em>. A filter template is defined one time. Creating a filter template is the only action that requires permission to create stored procedures in the database server. This step is typically performed by a database administrator.</li>
<li><em>Easy to subscribe</em>. Clients specify parameter values to create and subscribe to filtered scopes on an as-needed basis. This step requires only permission to insert rows in synchronization tables in the database server. This step can be performed by a user.</li>
<li><em>Easy to maintain</em>. Even when several parameters are combined and lots of filtered scopes are created, maintenance is simple because a single, parameter-based procedure is used to enumerate changes.</li>
</ul>
<p> </p>
<p><strong>Removing Scopes and Templates </strong></p>
<p>Sync Framework 2.1 adds the <strong>SqlSyncScopeDeprovisioning</strong> and <strong>SqlCeSyncScopeDeprovisioning</strong> classes to enable you to easily remove synchronization elements from databases that have been provisioned for synchronization. By using these classes you can remove scopes, filter templates, and the associated metadata tables, triggers, and stored procedures from your databases.</p>
<p><strong> </strong></p>
<p><strong>SQL Server Compact 3.5 SP2 Compatibility </strong></p>
<p>The Sync Framework 2.1 <strong>SqlCeSyncProvider</strong> database provider object uses SQL Server Compact 3.5 SP2. Existing SQL Server Compact databases are automatically upgraded when Sync Framework connects to them. Among other new features, SQL Server Compact 3.5 SP2 makes available a change tracking API that provides the ability to configure, enable, and disable change tracking on a table, and to access the change tracking data for the table. SQL Server Compact 3.5 SP2 can be downloaded <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=e497988a-c93a-404c-b161-3a0b323dce24">here</a>.</p>
<p>For more information about Sync Framework 2.1, including feature comparisons, walkthroughs, how-to documents, and API reference, see the <a href="http://go.microsoft.com/fwlink/?LinkID=199022&amp;clcid=0x409">product documentation</a>.</p>
<p>Stay in sync and <a href="http://bit.ly/bsQxqo">Download</a> Sync Framework 2.1 today and find out what synchronization can do for you!</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/sync-framework-2-1-has-arrived/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mobile Merge Replication Performance and Scalability Cheat Sheet</title>
		<link>http://robtiffany.com/mobile-merge-replication-performance-and-scalability-cheat-sheet/</link>
		<comments>http://robtiffany.com/mobile-merge-replication-performance-and-scalability-cheat-sheet/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 21:06:00 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Distributor]]></category>
		<category><![CDATA[Enterprise Data Synchronization]]></category>
		<category><![CDATA[High Availability]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Internet Information Services]]></category>
		<category><![CDATA[MEAP]]></category>
		<category><![CDATA[Merge Replication]]></category>
		<category><![CDATA[Mobile Enterprise Application Platform]]></category>
		<category><![CDATA[Mobile Middleware]]></category>
		<category><![CDATA[Publication]]></category>
		<category><![CDATA[Publisher]]></category>
		<category><![CDATA[SQL CE]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[SSCE]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[Subscriber]]></category>
		<category><![CDATA[Synchronize]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows Mobile]]></category>
		<category><![CDATA[Windows phone]]></category>
		<category><![CDATA[Windows Vista]]></category>
		<category><![CDATA[Windows XP]]></category>

		<guid isPermaLink="false">http://robtiffany.com/sql-server-compact/meap-mobile-merge-replication-performance-and-scalability-cheat-sheet</guid>
		<description><![CDATA[If your Mobile Enterprise Application Platform (MEAP) is using SQL Server Merge Replication to provide the mobile middleware and reliable wireless wire protocol for SQL Server Compact (SSCE) running on Windows Mobile 5/6.x devices + Windows XP/Vista/7 laptops, desktops and tablets; below is a guide to help you build the fastest, most scalable systems: <a href="http://robtiffany.com/mobile-merge-replication-performance-and-scalability-cheat-sheet/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If your Mobile Enterprise Application Platform (MEAP) is using SQL Server <em><strong>Merge Replication</strong></em> to provide the mobile middleware and reliable wireless wire protocol for SQL Server Compact (SSCE) running on Windows Mobile and Windows Embedded Handheld devices + Windows XP/Vista/7 tablets, laptops, desktops, slates, and netbooks; below is a guide to help you build the fastest, most scalable systems:</p>
<h2>Active Directory</h2>
<ul>
<li>Since your clients will be passing in their Domain\username + password credentials when they sync, both IIS and SQL Server will make auth requests of the Domain Controller. Ensure that you have at least a primary and backup Domain Controller, that the NTDS.dit disk drives are big enough to handle the creation of a large number of new AD DS objects (mobile users and groups), and that your servers have enough RAM to cache all those objects in memory.</li>
</ul>
<h2>Database Schema</h2>
<ul>
<li>Ensure your schema is sufficiently de-normalized so that you never have to perform more than a 4-way JOIN across tables. This affects server-side JOIN filters as well as SSCE performance.</li>
<li>To ensure uniqueness across all nodes participating in the sync infrastructure, use GUIDs for your primary keys so that SQL Server doesn’t have to deal with the overhead of managing Identity ranges. Make sure to mark your GUIDs as <strong>ROWGUIDCOL</strong> for that table so that Merge won’t try to add an additional <strong>Uniqueidentifier</strong> column to the table.  Don&#8217;t create clustered indexes when using GUIDs as primary keys because they will suffer horrible fragmentation that will rapidly degrade performance.  Just use a normal index.</li>
<li>Create clustered indexes for your primary keys when using Indentity columns, Datetime, or other natural keys.  Ensure that every column in every table that participates in a WHERE clause is indexed.</li>
</ul>
<h2>Distributor</h2>
<ul>
<li>If your network connection is fast and reliable like Wi-Fi or Ethernet, your SSCE client has more than 32 MB of free RAM, and SQL Server isn&#8217;t experiencing any deadlocks due to contention with ETL operations or too many concurrent Merge Agents, create a new Merge Agent Profile based on the <strong>High Volume Server-to-Server Profile</strong> so that SQL Server will perform more work per round-trip and speed up your synchronizations.</li>
<li>If you&#8217;re using a 2G/3G Wireless Wide Area Network connection, create a Merge Agent Profile based on the <strong>Default Profile</strong> so that SQL Server will perform less work and use fewer threads per round-trip during synchronization than the <strong>High Volume Server to Server Profile</strong> which will help to reduce server locking contention and perform less work per round trip which will make your synchronizations more likely to succeed.</li>
<li>In order to prevent SQL Server from performing Metadata Cleanup every time a Subscriber synchronizes, set the <strong>–MetadataRetentionCleanup</strong> parameter to <strong>0</strong>.</li>
<li>As SQL Server has to scale up to handle a higher number of concurrent users in the future, locking contention will increase due to more Merge Agents trying to perform work at the same time.  When this happens, adjust the parameters of the <strong>Default Profile</strong> so that both <strong> –SrcThreads</strong> and <strong>–DestThreads</strong> are equal to <strong>1</strong>.</li>
</ul>
<h2>Publication</h2>
<ul>
<li>When defining the Articles you’re going to sync, only check the minimum tables and columns needed by the Subscriber to successfully perform its work.</li>
<li>For Lookup/Reference tables that aren’t modified by the Subscriber, mark those as <strong>Download-only</strong> to prevent change-tracking metadata from being sent to the Subscriber.</li>
<li>Despite the fact the <strong>column-level</strong> tracking sends less data over the air, stick with <strong>row-level</strong> tracking so SQL Server won’t have to do as much work to track the changes.</li>
<li>Use the default conflict resolver where the “Server wins” unless you absolutely need a different manner of picking a winner during a conflict.</li>
<li>Use Static Filters to reduce the amount of server data going out to all Subscribers.</li>
<li>Make limited use of Parameterized Filters which are designed to reduce and further specify the subset of data going out to a particular Subscriber based on a HOST_NAME() which creates data partitions.  This powerful feature slows performance and reduces scalability with each additional filter, so it must be used sparingly.</li>
<li><em><strong>Keep filter queries simple</strong></em> and don’t use IN clauses, sub-selects or any kind of circular logic.</li>
<li>Strive to always create &#8220;well-partitioned&#8221; Articles where all changes that are uploaded/downloaded are mapped to only the single partition ID for best performance and scalability.
<ul>
<li>When using Parameterized Filters, always create non-overlapping data partitions where each row from a filtered table only goes to a single Subscriber instead of more than one which will avoid the use of certain Merge metadata tables.</li>
<li>Each Article in this scenario can only be pubished to a single Publication</li>
<li>A Subscriber cannot insert rows that do not belong to its partition ID.</li>
<li>A Subscriber cannot update columns that are involved in filtering.</li>
<li>In a join filter hierarchy, a regular article cannot be the parent of a &#8220;well-partitioned&#8221; article.</li>
<li>The join filter in which a well-partitioned article is the child must have the join_unique_key set to a value of 1 which relates to the <strong>Unique key</strong> check box of the Add Join dialog.  This means there&#8217;s a one-to-one or one-to-many relationship with the foreign key.</li>
<li>Each &#8220;well-partitioned&#8221; Article can have only one subset or join filter. The article can have a subset filter and be the parent of a join filter, but cannot have a subset filter and be the child of a join filter.</li>
</ul>
</li>
<li>Never extend a filter out to more than 4 joined tables.</li>
<li>Do not filter tables that are primarily lookup/reference tables, small tables, and tables with data that does not change.</li>
<li>Schedule the Snapshot Agent to run once per day to create an unfiltered schema Snapshot.</li>
<li>Set your Subscriptions to expire as soon as possible to keep the amount change-tracking metadata SQL Server has to manage to an absolute minimum. Normally, set the value to 2 to accommodate 3-day weekends since 24 hours are automatically added to the time to account for multiple time zones. If server-side change tracking isn’t needed and Subscribers are pulling down a new database every day and aren’t uploading data, then set the expiration value to 1.</li>
<li>Set <strong>Allow parameterized filters</strong> equal to True.</li>
<li>Set <strong>Validate Subscribers</strong> equal to HOST_NAME().</li>
<li>Set <strong>Precompute partitions</strong> equal to True to allow SQL Server to optimize synchronization by computing in advance which data rows belong in which partitions.</li>
<li>Set <strong>Optimize synchronization</strong> equal to False if <strong>Precompute partitions</strong> is equal to True.  Otherwise set it to True to optimize filtered Subscriptions by storing more metadata at the Publisher.</li>
<li>Set <strong>Limit concurrent processes</strong> equal to True.</li>
<li>Set <strong>Maximum concurrent processes</strong> equal to the number of SQL Server processor cores.  If exceesive locking contention occurs, reduce the number of concurrent processes until the problem is fixed.</li>
<li>Set <strong>Replicate schema changes</strong> equal to True.</li>
<li>Check <strong>Automatically define a partition and generate a snapshot if needed when a new Subscriber tries to synchronize</strong>. This will reduce Initialization times since SQL Server creates and applies snapshots using the fast BCP utility instead of a series of slower SELECT and INSERT statements.</li>
<li>Add data partitions based on unique HOST_NAMEs and schedule the Snapshot Agent to create those filtered Snapshots nightly or on the weekend so they’ll be built using the fast BCP utility and waiting for new Subscribers to download in the morning.</li>
<li>Ensure that SQL Server has 1 processor core and 2 GB of RAM for every 100 concurrent Subscribers utilizing bi-directional sync. Add 1 core and 2 GB of RAM server for every additional 100 concurrent Subscribers you want to add to the system.  Never add more Subscribers and/or IIS servers without also adding new cores and RAM to the Publisher.</li>
<li>Turn off <strong>Hyperthreading</strong> in the BIOS of the SQL Server as it has been known to degrade SQL Server performance.</li>
<li>Do not add your own user-defined triggers to tables on a Published database since Merge places 3 triggers on each table already.</li>
<li>Add one or more <strong>Filegroups</strong> to your database to contain multiple, secondary database files spread out across many physical disks.</li>
<li>Limit use of large object types such as text, ntext, image, varchar(max), nvarchar(max) or varbinary(max) as they require a significant memory allocation and will negatively impact performance.</li>
<li>Set SQL Servers’s minimum and maximum memory usage to within 2 GB of total system memory so it doesn’t have to allocate more memory on-demand.</li>
<li>Always use SQL Server 2008 R2 and Windows Server 2008 R2 since they work better together because they take advantage of the next generation networking stack which dramatically increases network throughput. They can also scale up as high as 256 cores.</li>
<li>Due to how Merge Replication tracks changes with triggers, Merge Agents, and tracking tables, it will create locking contention withDML/ ETL operations.  This contention degrades server performance which negatively impacts sync times with devices.  This contention should be mitgated by performing large INSERT/UPDATE/DELETE DML/ETL operations during a nightly maintenance window when Subscribers aren’t synchronizing.</li>
<li>Since Published databases result in slower DML/ETL operations, perform changes in bulk by using XML Stored Procedures to boost performance.</li>
<li>To improve the performance of pre-computed partitions when DML/ETL operations result in lots of data changes, ensure that changes to a Parent table in a join filter are made before corresponding changes in the child tables.  This means that when DML/ETL operations are pushing new data into SQL Server, they must add master data to the parent filter table first, and then add detail data to all the related child tables second, in order for that data to be pre-computed and optimized for sync.</li>
<li>Create filter partitions based on things that don’t change every day.  Partitions that are added and deleted from SQL Server and Subscribers that move from one partition to another is very disruptive to the performance of Merge Replication.</li>
<li>Always perform initializations and re-initializations over Wi-Fi or Ethernet when the device is docked because this is the slowest operation where the entire database must be downloaded instead of just deltas.  To determine rough estimates for initialization, multiply the size of the resulting SSCE .sdf file <strong>x</strong> the bandwidth speed available to the device.  A file copy over the expected network will also yield estimates for mininum sync times.  These times don&#8217;t include the work SQL Server and IIS must perform to provide the data or data INSERT times on SSCE.</li>
<li>If your SQL Server Publisher hits a saturation point with too many concurrent mobile Subscribers, you can scale it out creating a Server/Push Republishing hierarchy. Put the primary SQL Server Publisher at the top of the pyramid and have two or more SQL Servers subscribe to it. These can be unfiltered Subscriptions where all SQL Servers get the same data or the Subscribers can filter their data feeds by region for example. Then have the Subscribing SQL Servers Publish their Subscription for consumption by mobile SSCE clients.</li>
<li>Create just a single Publication.</li>
</ul>
<h2>Internet Information Services</h2>
<ul>
<li>Use the x64 version of the <strong>SQL Server Compact 3.5 SP2 Server Tools</strong> with Windows Server 2008 R2 running inside IIS 7.5.</li>
<li>Use a single Server Agent in a single Virtual Directory.</li>
<li>Ensure the IIS Virtual Directory where the Server Agent resides is on a fast solid-state drive that’s separate from the disk where Windows Server is installed to better support file I/O.</li>
<li>Use a low-end server with 2 processor cores and 2 GB of RAM to support 400 concurrent Subscribers queued at the same time.</li>
<li>Set the MAX<strong>_THREADS_PER_POOL </strong>Server Agent registry key equal to 2 to match the IIS processor cores and RAM. Do not set this value to a higher number than the number of cores.</li>
<li>Set the <strong>MAX_PENDING_REQUEST</strong> Server Agent registry key equal to 400 which means the Server Agent will queue up to 400 concurrent Subscribers waiting for one of the 2 worker threads to become available to sync with SQL Server.</li>
<li>Set the <strong>IIS Connection Limits</strong> property to 400 to prevent an unlimited number of connections reaching the Server Agent.</li>
<li>Add a new load-balanced IIS server for every additional 400 concurrent Subscribers you want to add to the system.</li>
</ul>
<h2>Subscriber</h2>
<ul>
<li>Use the appropriate x64, x86 or ARM version of SQL Server Compact 3.5 SP2 to take advantage of the <strong>PostSyncCleanup</strong> property of the <strong>SqlCeReplication</strong> object that can reduce the time it takes to perform an initial synchronization. Set the <strong>PostSyncCleanup</strong> property equal to 3 where neither <strong>UpdateStats</strong> nor <strong>CleanByRetention</strong> are performed.</li>
<li>Increase the <strong>Max Buffer Size</strong> connection string parameter to <strong>1024</strong> on a phone and <strong>4096</strong> on a PC to boost both replication and SQL query processing performance. If you have more RAM available, set those values even higher until you reach the law of diminishing returns.</li>
<li>Keep your SSCE database compact and fast by setting the <strong>Autoshrink Threshold</strong> connection string parameter to 10 so it starts reclaiming empty data pages once the database has become 10% fragmented.</li>
<li>Replication performance testing must be performed using actual PDAs to observe how available RAM, storage space and CPU speed affect moving data into the device’s memory area and how quickly this data is inserted into the SSCE database tables.  Since the SSCE database doubles in size during replication, the device must have enough storage available or the operation will fail.  Having plenty of available RAM is important so that SSCE can utilize its memory buffer to complete a Merge Replication operation more quickly.  With plenty of available RAM and storage, a fast CPU will make all operations faster.</li>
<li>The PDA must have at least an extra 32 MB of available free RAM that can be used by the .NET Compact Framework (NETCF) application.  If additional applications are running on the device at the same time, even more RAM is needed.  If a NETCF application has insufficient RAM is will discard its compiled code and run in interpreted mode which will slow the application down.  If the NETCF app is still under memory pressure after discarding compiled code, Windows Mobile will first tell the application to return free memory to the operating system and then will terminate the app if needed.</li>
<li>Set the <strong>CompressionLevel</strong> property of the <strong>SqlCeReplication </strong>object to 0 for fast connections and increment it from 1 to 6 on slower connections like GPRS to increase speed and reduce bandwidth consumption.</li>
<li>Tune the <strong>ConnectionRetryTimeout</strong>, <strong>ConnectTimeout</strong>, <strong>ReceiveTimeout</strong> and <strong>SendTimeout</strong> properties of the <strong>SqlCeReplication</strong> object based on expected bandwidth speeds:</li>
</ul>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="160"><strong>Property</strong></td>
<td valign="top" width="160"><strong>High Bandwidth</strong></td>
<td valign="top" width="160"><strong>Medium Bandwidth</strong></td>
<td valign="top" width="160"><strong>Low Bandwidth</strong></td>
</tr>
<tr>
<td valign="top" width="160">ConnectionRetryTimeout</td>
<td valign="top" width="160">30</td>
<td valign="top" width="160">60</td>
<td valign="top" width="160">120</td>
</tr>
<tr>
<td valign="top" width="160">ConnectTimeout</td>
<td valign="top" width="160">3000</td>
<td valign="top" width="160">6000</td>
<td valign="top" width="160">12000</td>
</tr>
<tr>
<td valign="top" width="160">ReceiveTimeout</td>
<td valign="top" width="160">1000</td>
<td valign="top" width="160">3000</td>
<td valign="top" width="160">6000</td>
</tr>
<tr>
<td valign="top" width="160">SendTimeout</td>
<td valign="top" width="160">1000</td>
<td valign="top" width="160">3000</td>
<td valign="top" width="160">6000</td>
</tr>
</tbody>
</table>
<ul>
<li>You can decrease potentially slow SSCE file I/O by adjusting the Flush Interval connection string parameter to write committed transactions to disk less often than the default of every 10 seconds.  Test longer intervals between flushes like 20 or 30 seconds. Keep in mind that these transactions can be lost if the disk or system fails before flushing occurs so be careful.</li>
<li>When replicating data that has been captured in the field by the device, perform Upload-only syncs to shorten the duration.</li>
</ul>
<h2>Storage</h2>
<ul>
<li>Use a Fibre Channel SAN with 15k RPM or solid-state disks for best I/O performance.</li>
<li>Databases should reside on a RAID 10, unshared LUN comprised of at least 6 disks.</li>
<li>Database logs should reside on a RAID 10, unshared LUN comprised of at least 6 disks.</li>
<li>Tempdb should reside on a RAID 10, unshared LUN comprised of at least 6 disks.</li>
<li>The Tempdb log should reside on a RAID 10, unshared LUN comprised of at least 6 disks.</li>
<li>The Snapshot share should reside on a RAID 10, unshared LUN comprised of at least 6 disks.  This disk array should be large enough to accommodate a growing number of filtered Snapshots. Snapshot folders for Subscribers that no longer use the system must be manually deleted.</li>
<li>Merge Replication metadata tables should reside on a RAID 10, unshared LUN comprised of at least 6 disks.</li>
<li>Increase your Host Bus Adapter (HBA) queue depths to 64.</li>
<li>Your Publication database should be broken up into half the number of files as the SQL Server has processor cores. Each file must be the same size.</li>
<li>Tempdb should be pre-sized with an auto-growth increment of 10%. It should be broken up into the same number of files as the SQL Server has processor cores. Each file must be the same size.</li>
</ul>
<h2>High Availability</h2>
<ul>
<li>Load-balance the IIS servers to scale them out. Enable Server Affinity (stickiness) since the <strong>Replication Session Control Blocks</strong> that transmit data between the Server Agent and SSCE are stateful. Test to ensure that your load-balancer is actually sending equal amounts of Subscriber sync traffic to each IIS server.  Some load-balancers can erroneously send all traffic to a single IIS server if not properly configured.</li>
<li>Implement Windows Clustering so that SQL Server can failover to a second node.</li>
<li>Using SQL Server Mirroring so that your Published database will failover to a standby server.</li>
<li>Make a second SQL Server into an unfiltered Subscriber to your Publisher so that it can take over Merge Replication duties for mobile clients as a Republisher if the primary SQL Server fails. SSCE clients would just have to reinitialize their Subscriptions to begin synchronizing with the new Republisher.</li>
</ul>
<h2>Ongoing Maintenance</h2>
<ul>
<li>Use the Replication Monitor to have a real-time view of the synchronization performance of all your Subscribers.</li>
<li>Use the web-based SQL Server Compact Server Agent Statistics and Diagnostics tools to monitor the health and activity of the Server Agent running on IIS.</li>
<li>Create a SQL Job to execute the <strong>sp_MSmakegeneration</strong> stored procedure after large DML operations. Regular execution after INSERTING/UPDATING/DELETING data from either DML/ETL operations or after receiving lots of changes from Subscribers will maintain subsequent sync performance. Executing this stored procedure from the server-side is preferable to having it executed as a result of a Subscriber sync which would block all other Subscribers.</li>
<li>During your nightly maintenance window, rebuild the indexes and update the statistics of the following Merge Replication metadata tables:
<ul>
<li><strong>MSmerge_contents</strong></li>
<li><strong>MSmerge_tombstone</strong></li>
<li><strong>MSmerge_genhistory</strong></li>
<li><strong>MSmerge_current_partition_mappings</strong></li>
<li><strong>MSmerge_past_partition_mappings</strong></li>
<li><strong>MSmerge_generation_partition_mappings</strong></li>
</ul>
</li>
<li>If you notice performance degradation during the day due to a large number of Subscribers making large changes to the database, you can updates the statistics (with fullscan) of the Merge Replication metadata tables more frequently throughout the day to force stored proc recompiles to get a better query plan.
<ul>
<li>UPDATE STATISTICS MSmerge_generation_partition_mappings WITH FULLSCAN</li>
<li>UPDATE STATISTICS MSmerge_genhistory WITH FULLSCAN</li>
</ul>
</li>
<li>Rebuild/defrag indexes on your database tables and Merge Replication metadata tables throughout the day to reduce locking contention and maintain performance.</li>
<li>Use the Missing Indexes feature of SQL Server to tell you which indexes you could add that would give your system a performance boost. Do not add recommended indexes to Merge system tables.</li>
<li>Use the Database Engine Tuning Advisor to give you comprehensive performance tuning recommendations that cover every aspect of SQL Server.</li>
<li>Monitor the performance of the following counters:
<ul>
<li><strong>Processor Object: % Processor Time: </strong>This counter represents the percentage of processor utilization. A value over 80% is a CPU bottleneck.</li>
<li><strong>System Object: Processor Queue Length: </strong>This counter represents the number of threads that are delayed in the processor Ready Queue and waiting to be scheduled for execution. A value over 2 is bottleneck and shows that there is more work available than the processor can handle. Remember to divide the value by the number of processor cores on your server.</li>
<li><strong>Memory Object: Available Mbytes: </strong>This counter represents the amount of physical memory available for allocation to a process or for system use. Values below 10% of total system RAM indicate that you need to add additional RAM to your server.</li>
<li><strong>PhysicalDisk Object: % Disk Time: </strong>This counter represents the percentage of time that the selected disk is busy responding to read or write requests. A value greater than 50% is an I/O bottleneck.</li>
<li><strong>PhysicalDisk Object: Average Disk Queue Length: </strong>This counter represents the average number of read/write requests that are queued on a given physical disk. If your disk queue length is greater than 2, you’ve got an I/O bottleneck with too many read/write operations waiting to be performed.</li>
<li><strong>PhysicalDisk Object: Average Disk Seconds/Read and Disk Seconds/Write: </strong>These counters represent the average time in seconds of a read or write of data to and from a disk. A value of less than 10 ms is what you’re shooting for in terms of best performance. You can get by with subpar values between 10 – 20 ms but anything above that is considered slow. Times above 50 ms represent a very serious I/O bottleneck.</li>
<li><strong>PhysicalDisk Object: Average Disk Reads/Second and Disk Writes/Second: </strong>These counters represent the rate of read and write operations against a given disk. You need to ensure that these values stay below 85% of a disk’s capacity by adding disks or reducing the load from SQL Server. Disk access times will increase exponentially when you get beyond 85% capacity.</li>
</ul>
</li>
<li>A limited number of database schema changes can be made and synchronized down to SSCE Subscribers without any code changes which makes it easier to update your system as it evolves over time.</li>
<li>Use a Merge Replication Test Harness to stress test the entire system.  The ability to simulate hundreds or thousands of concurrent synchronizing Subscribers allows you to monitor performance and the load on the system.  This is helpful in properly configuring and tuning SQL Server, IIS, and the Windows Mobile devices.  It will tell you where you’re having problems and it will let you predict how much server hardware you will need to support growing numbers of Subscribers over time.  It’s also very important to simulate worst-case scenarios that you never expect to happen.</li>
</ul>
<p>I hope this information sufficiently empowers you to take on the largest MEAP solutions that involve SQL Server Merge Replication and SQL Server Compact.  If you need a deeper dive, go check out my book on Enterprise Data Synchronization <a title="http://www.amazon.com/Enterprise-Synchronization-Microsoft-Compact-Replication/dp/0979891213/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1271964573&amp;sr=1-1" href="http://www.amazon.com/Enterprise-Synchronization-Microsoft-Compact-Replication/dp/0979891213/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1271964573&amp;sr=1-1">http://www.amazon.com/Enterprise-Synchronization-Microsoft-Compact-Replication/dp/0979891213/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1271964573&amp;sr=1-1</a> over at Amazon.  Now go build a fast and scalable solution for your company or your customers.</p>
<p>Best Regards,</p>
<p>Rob</p>
<p>P.S.  If your solution doesn&#8217;t require all the advanced features found in Merge Replication, I highly recommend you use Remote Data Access (RDA).  This is a much simpler sync technology that&#8217;s extremely fast, scalable, and easier to manage.</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/mobile-merge-replication-performance-and-scalability-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Microsoft SQL Server Compact 3.5 SP2 has Arrived</title>
		<link>http://robtiffany.com/microsoft-sql-server-compact-3-5-sp2-has-arrived/</link>
		<comments>http://robtiffany.com/microsoft-sql-server-compact-3-5-sp2-has-arrived/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:35:00 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[Sync]]></category>
		<category><![CDATA[Merge Replication]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Remote Data Access]]></category>
		<category><![CDATA[SQL CE]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SSCE]]></category>
		<category><![CDATA[Sync Framework]]></category>
		<category><![CDATA[Sync Services for ADO.NET]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows phone]]></category>

		<guid isPermaLink="false">http://robtiffany.com/sql-server-compact/microsoft-sql-server-compact-3-5-sp2-has-arrived</guid>
		<description><![CDATA[My favorite embedded database for Windows Phones, laptops, tablets and desktops has been released to the Web along with Visual Studio 2010. New features for SQL Server Compact 3.5 SP2 include: Supports working with a SQL Server Compact 3.5 database &#8230; <a href="http://robtiffany.com/microsoft-sql-server-compact-3-5-sp2-has-arrived/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My favorite embedded database for Windows Phones, laptops, tablets and desktops has been released to the Web along with Visual Studio 2010. </p>
<p>New features for SQL Server Compact 3.5 SP2 include:<a href="http://robtiffany.com/wp-content/uploads/2010/04/SSCE.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="SSCE" border="0" alt="SSCE" align="right" src="http://robtiffany.com/wp-content/uploads/2010/04/SSCE_thumb.png" width="123" height="125" /></a></p>
<ul>
<li>Supports working with a SQL Server Compact 3.5 database using the Transact-SQL Editor in Visual Studio 2010. The Transact-SQL Editor can be used to run free-text Transact-SQL queries against a SQL Server Compact 3.5 database. The Transact-SQL Editor also provides the ability to view and save detailed estimated and actual query show-plans for SQL Server Compact 3.5 databases. Previously, the functionality provided by the Transact-SQL Editor was only available through SQL Server Management Studio. </li>
<li>New classes and members named SqlCeChangeTracking have been added to the System.Data.SqlServerCe namespace to expose the internal change tracking feature used by Sync Framework to track changes in the database. The SQL Server Compact change tracking infrastructure maintains information about inserts, deletes, and updates performed on a table that has been enabled for change tracking. This information is stored both in columns added to the tracked table and in system tables maintained by the tracking infrastructure. By using System.Data.SqlServerCe.SqlCeChangeTracking one can configure, enable, and disable change tracking on a table, and also access the tracking data maintained for a table. The API can be used to provide functionality in a number of scenarios. For example it can be used to provide custom implementations of client-to-server or client-to-client sync for occasionally connected systems (OCS) or to implement a custom listener application. </li>
<li>The managed assemblies of SQL Server Compact for use by the applications that privately deploy SQL Server Compact are installed in the folder %Program Files%\Microsoft SQL Server Compact Edition\v3.5\Private. Using these assemblies ensure that the application uses the privately deployed version of Compact even when a lower version of SQL Server Compact 3.5 is installed in the GAC. </li>
<li>Visual Studio 2010 installs both the 32-bit and 64-bit versions of SQL Server Compact 3.5 SP2 on a 64-bit machine. If a SQL Server Compact application is deployed using Click Once in Visual Studio 2010 then both the 32-bit and the 64-bit version of SQL Server Compact are installed on a 64-bit machine </li>
<li>SQL Server Compact 3.5 SP2 adds support for Windows Mobile 6.5, Windows 7 and Windows Server 2008 R2, and can sync data using Merge Replication and RDA with SQL Server 2008 R2 November CTP. </li>
<li>The SqlCeReplication object gets a new property called PostSyncCleanup which you can use to prevent SQL Server Compact from Updating Statistics after an initial Merge Replication initialization.&#160; This has the potential to shave a substantial amount of time off of your initial syncs depending on the size of your database. </li>
</ul>
<p>&#160;</p>
<p>In addition to these new features, the following hotfixes from SQL Server 2005 Compact Edition or SQL Server Compact 3.5 SP1 have been rolled up in SQL Server Compact 3.5 SP2:</p>
<ul>
<li><a href="http://support.microsoft.com/kb/953259">http://support.microsoft.com/kb/953259</a>: Error message when you run an SQL statement that uses the Charindex function in a database that uses the Czech locale in SQL Server 2005 Compact Edition: &quot;The function is not recognized by SQL Server Compact Edition&quot; </li>
<li><a href="http://support.microsoft.com/kb/958478">http://support.microsoft.com/kb/958478</a>: Error message when you run a &quot;LINQ to Entities&quot; query that uses a string parameter or a binary parameter against a SQL Server Compact 3.5 database: &quot;The ntext and image data types cannot be used in WHERE, HAVING, GROUP BY, ON, or IN clauses&quot; </li>
<li><a href="http://support.microsoft.com/kb/959697">http://support.microsoft.com/kb/959697</a>: Error message when you try to open a database file from a CD in SQL Server Compact 3.5 with Service Pack 1: &quot;Internal Error using read only database file&quot; </li>
<li><a href="http://support.microsoft.com/kb/960142">http://support.microsoft.com/kb/960142</a>: An error message is logged, and the synchronization may take a long time to finish when you use an application to synchronize a merge replication that contains a SQL Server 2005 Compact Edition subscriber </li>
<li><a href="http://support.microsoft.com/kb/963060">http://support.microsoft.com/kb/963060</a>: An error message is logged, and the synchronization may take a long time to finish when you synchronize a merge replication that contains a SQL Server Compact 3.5 subscriber: &quot;UpdateStatistics Start app=&lt;UserAppName&gt;.exe&quot; </li>
<li><a href="http://support.microsoft.com/kb/967963">http://support.microsoft.com/kb/967963</a>: Some rows are deleted when you repair a database by using the Repair method together with the RepairOption.RecoverCorruptedRows option in SQL Server 2005 Compact Edition and in SQL Server Compact 3.5 </li>
<li><a href="http://support.microsoft.com/kb/968171">http://support.microsoft.com/kb/968171</a>: Error message when you try to create an encrypted database in SQL Server 2005 Compact Edition: &quot;The operating system does not support encryption&quot; </li>
<li><a href="http://support.microsoft.com/kb/968864/EN-US">http://support.microsoft.com/kb/968864</a>: Error message when you run a query in SQL Server Compact 3.5: &quot;The column name cannot be resolved to a table. Specify the table to which the column belongs&quot; </li>
<li><a href="http://support.microsoft.com/kb/969858/en-us">http://support.microsoft.com/kb/969858</a>: Non-convergence occurs when you synchronize a SQL Server Compact 3.5 client database with the server by using Sync Services for ADO.NET in a Hub-And-Spoke configuration </li>
<li><a href="http://support.microsoft.com/kb/970269/EN-US">http://support.microsoft.com/kb/970269</a>: Access violations occur when you run an application under heavy load conditions after you install the 64-bit version SQL Server Compact 3.5 Service Pack 1 </li>
<li><a href="http://support.microsoft.com/kb/970414">http://support.microsoft.com/kb/970414</a>: Initial synchronization of a replication to SQL Server Compact 3.5 subscribers takes significant time to finish </li>
<li><a href="http://support.microsoft.com/kb/970915/EN-US">http://support.microsoft.com/kb/970915</a>: Error message when you synchronize a merge replication with SQL Server 2005 Compact Edition subscribers: &quot;A column ID occurred more than once in the specification. HRESULT 0x80040E3E (0)&quot; </li>
<li><a href="http://support.microsoft.com/kb/971027">http://support.microsoft.com/kb/971027</a>: Error message when you upgrade a very large database to SQL Server Compact 3.5: &quot;The database file is larger than the configured maximum database size. This setting takes effect on the first concurrent database connection only&quot; </li>
<li><a href="http://support.microsoft.com/kb/971273">http://support.microsoft.com/kb/971273</a>: You do not receive error messages when you run a query in a managed application that returns columns of invalid values in SQL Server Compact 3.5 </li>
<li><a href="http://support.microsoft.com/kb/971970/EN-US">http://support.microsoft.com/kb/971970</a>: You cannot insert rows or upload changes into the SQL Server 2005 Compact Edition subscriber tables after you run the &quot;sp_changemergearticle&quot; stored procedure or you add a new merge publication article when another article has an IDENTITY column </li>
<li><a href="http://support.microsoft.com/kb/972002/EN-US">http://support.microsoft.com/kb/972002</a>: Error message when you try to create an encrypted database in SQL Server Compact 3.5: &quot;The operating system does not support encryption&quot; </li>
<li><a href="http://support.microsoft.com/kb/972390">http://support.microsoft.com/kb/972390</a>: The application enters into an infinite loop when you run an application that uses Microsoft Synchronization Services for ADO.NET to synchronize a SQL Server Compact 3.5 database </li>
<li><a href="http://support.microsoft.com/kb/972776">http://support.microsoft.com/kb/972776</a>: When the application calls the SqlCeConnection.Close method or the SqlCeConnection.Dispose method in SQL Server Compact 3.5, the application may stop responding at the method call </li>
<li><a href="http://support.microsoft.com/kb/974068">http://support.microsoft.com/kb/974068</a>: Error message when an application inserts a value into a foreign key column in SQL Server Compact 3.5: &quot;No key matching the described characteristics could be found within the current range&quot; </li>
</ul>
<p>&#160;</p>
<p>Web downloads for SQL Server Compact 3.5 SP2 is as listed below: </p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=E497988A-C93A-404C-B161-3A0B323DCE24">SQL Server Compact 3.5 SP2 for Windows desktop (32-bit and 64-bit)</a></p>
<p><b>Note that the file available for download is a 6 MB self-extracting executable (exe) file that contains the 32-bit and the 64-bit Windows Installer (MSI) files for installing SQL Server Compact 3.5 SP2 on a 32-bit and a 64-bit Computer. It is important to install both the 32-bit and the 64-bit version of the SQL Server Compact 3.5 SP2 MSI on a 64-bit Computer. Existing SQL Server Compact 3.5 applications may fail if only the 32-bit version of the MSI file is installed on the 64-bit computer. Developers should chain both the 32-bit and the 64-bit MSI files with their applications and install both of them on the 64-bit Computer. Refer to the <a href="http://support.microsoft.com/kb/974247">KB article</a> for more information.</b></p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=5544C638-C532-48E3-871C-58B49C5D855C">SQL Server Compact 3.5 SP2 for Windows mobile devices (all platforms &amp; processors)</a></p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=5DEEC9D5-C216-446E-A003-5D6026AD19B3">SQL Server Compact 3.5 SP2 Server Tools (32-bit and 64-bit)</a></p>
<p><a href="http://go.microsoft.com/fwlink/?LinkId=187303">SQL Server Compact 3.5 SP2 Books Online</a> (Note that the books online will be available for download by the third week of April 2010)</p>
<p><a href="http://code.msdn.microsoft.com/sqlce/">SQL Server Compact 3.5 SP2 Samples</a></p>
<p><a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx">Visual Studio 2010 and .NET Framework 4</a></p>
<p>This is a great release for SQL Server Compact that adds some important new features, squashes a bunch of bugs and adds support for our newest operating systems.&#160; I strongly recommend you update your existing SSCE runtimes with SQL Server Compact 3.5 SP2.</p>
<p>Keep on Synching,</p>
<p>Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/microsoft-sql-server-compact-3-5-sp2-has-arrived/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What ever happened to RDA?</title>
		<link>http://robtiffany.com/what-ever-happened-to-rda/</link>
		<comments>http://robtiffany.com/what-ever-happened-to-rda/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 05:34:47 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Sync]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DataSet]]></category>
		<category><![CDATA[DB2]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[MEDC]]></category>
		<category><![CDATA[Merge Replication]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[P2P]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Remote Data Access]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[SSCE]]></category>
		<category><![CDATA[Sync Framework]]></category>
		<category><![CDATA[Sync Services for ADO.NET]]></category>
		<category><![CDATA[Synchronize]]></category>
		<category><![CDATA[Transactional Replication]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Windows Mobile]]></category>
		<category><![CDATA[Windows phones]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=3</guid>
		<description><![CDATA[Who remembers using Remote Data Access to synchronize data between SQL Server and SQL Server Compact?  I certainly do! Before I dove head first into the world of Merge Replication, I always used RDA to get my customers up and &#8230; <a href="http://robtiffany.com/what-ever-happened-to-rda/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Who remembers using Remote Data Access to synchronize data between SQL Server and SQL Server Compact?  I certainly do!</strong></p>
<p>Before I dove head first into the world of Merge Replication, I always used RDA to get my customers up and running quickly.  Mobilizing an organization’s workforce quickly and easily is what it’s all about so they can start reaping the benefits.  In addition to a speedy time to market, there’s no faster or more scalable mobile sync technology on the market anywhere. </p>
<p><strong>So why wouldn’t I always use RDA?  Here’s a quick list:</strong></p>
<ol>
<li>You’re using Identity columns.</li>
<li>You want to replicate schema changes to the client.</li>
<li>You want change tracking on both the client and server to perform diffs of each of the tables during a sync instead of re-downloading the entire table.</li>
<li>You want to automatically resolve conflicts that arise when 2 people update the same data.</li>
<li>You want referential integrity constraints to be pushed down to the client database from SQL Server.</li>
<li>You don’t want to write code to perform synchronization or filter data.</li>
</ol>
<p>If anything on the above list applied to you, you would shift to Merge Replication because it could manage ranges of Identity columns, push down schema changes, only sync data differences, resolve conflicts and push down a database’s referential integrity constraints.  Merge requires almost no code to get started and tables and columns are filtered visually via a wizard.</p>
<p><strong>So why might you choose to use RDA?  Here’s another list:</strong></p>
<ol>
<li>Your Primary Keys use GUIDs instead of Identity columns.</li>
<li>Users don’t overwrite each other’s data so you don’t need conflict resolution.  The rule of “Last in Wins” works for you.</li>
<li>While you want indexes to be pushed down, you don’t care if your local SSCE database has referential integrity constraints applied.</li>
<li>You want to wrap the changes you upload to SQL Server in a transaction so that all changes are applied or none of them are.</li>
<li>Change tracking on the client is good enough and re-downloading updated server tables doesn’t take too long.</li>
<li>You developers don’t mind writing some sync code.</li>
<li>Be able to execute SQL and Stored Procedures directly against SQL Server via IIS.</li>
<li>You&#8217;re downloading read-only data.</li>
</ol>
<p>If your solution meets the criteria in the list above, you’re probably a good candidate for using RDA instead of Merge.  Are there any other choices out there?</p>
<p>Back at MEDC 2007, we announced a new data replication technology for devices called Occasionally Connected Sync that would sit somewhere between RDA and Merge.  OCS as it used to be called was renamed Sync Services for ADO.NET and then was eventually merged into the Sync Framework. </p>
<p><strong>The Sync Framework is a developer-focused technology:</strong></p>
<ol>
<li>Supports conflict resolution.</li>
<li>Change tracking on the server as well as the client so that only data differences are exchanged.</li>
<li>Peer to Peer sync in the forthcoming v2 of Sync Framework.</li>
<li>Sync with databases other than SQL Server.</li>
<li>Best suited for SSCE running on a desktop or laptop.</li>
</ol>
<p>The clearest differentiation that the Sync Framework has over Merge is its provider model which allows it to sync with other ADO.NET databases like Oracle or DB2.  SQL Server supports built-in P2P Transactional replication and v2 of the Sync Framework will allow you to do this via WCF.  If you development team doesn’t mind writing lots of sync code and needs to support scenarios like synchronizing with other databases from SSCE on the desktop, then the Sync Framework might be the way to go for you.  I wouldn’t yet recommend the Sync Framework for device sync since its wire protocol is currently based on the DataSet which may cause out of memory errors on Windows phones with limited working sets.</p>
<p><strong>So where does this leave RDA?</strong></p>
<p>The reason I’m writing this blog post is because time and time again I run into customer sync scenarios that don’t always need the power of Merge or the extra flexibility of the Sync Framework.  Most field service applications follow the same kind of pattern:</p>
<ol>
<li>Lots of download-only lookup/reference tables that aren’t changed by the user.</li>
<li>Tables that are pushed down to the device that tell a user where to go and what to do.</li>
<li>Tables (sometimes empty) that are used to capture data from the user in the field that are upload-only.</li>
</ol>
<p>These kinds of schemas don’t require conflict resolvers or server change tracking and are therefore well suited for RDA. </p>
<p><strong>What’s the big benefit of using RDA if a sync scenario meets its criteria?</strong></p>
<ol>
<li>You won’t modify SQL Server’s schema with GUIDs and Triggers.</li>
<li>You won’t degrade the performance of SQL Server by having it track changes and maintain extra metadata.</li>
<li>You will have the fastest and most scalable sync solution with least amount of hardware.</li>
<li>Time to market is shorter.</li>
</ol>
<p>The big takeaway here is that I want you to consider your sync solution carefully before choosing a technology.  If your customer’s needs are met by RDA, then you should use it and reap the benefits of developing and deploying a simpler solution with fewer moving parts.</p>
<p><strong>Remember Occam&#8217;s Razor.</strong></p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/what-ever-happened-to-rda/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

