Ms sync

Рейтинг: 4.2/5.0 (1215 проголосовавших)


Making Microsoft Sync Framework work with PostgreSql

Making Microsoft Sync Framework work with PostgreSql

Posted by Roopesh Shenoy on Mar 18, 2011

reading list
  • Add to reading list
  • View my

    reading list

  • We failed to create the bookmark.

    If the behaviour persists please contact us.

    NOTE: QCon London - the 10th international software development conference - Mar 7-11, 2016. 100+ expert practitioner speakers, +1,100 attendees, 18 tracks to cover topics driving the evolution of software development today. Get more details or register now.

    Microsoft Sync Framework is a Data synchronization platform from Microsoft to build offline-enabled applications. Sync Framework can be used for occasionally connected clients to connect to central server, for peer-peer applications and a whole lot of applications where data needs to be synchronized between multiple data stores. There are in-built mechanisms for conflict-detection and handling.

    Microsoft first announced Sync Framework CTP in late 2007 - suggesting that it is going to make building sync applications much easier than before, allowing huge amount of reuse for synchronization logic through providers and overall improvement in the data-anywhere philosophy.

    It has been more than three years since then and it looks like the promise is being delivered - Microsoft has managed to make it a comprehensive and robust framework that supports synchronization of data in a number of ways. And Microsoft has built a number of solutions on top of this framework, especially with SQL Server, SQL Azure and Windows Azure Storage.

    Although most of Microsoft’s marketing efforts for Sync Framework revolve around its’ own database products, it must be said that the framework itself can work with any data-store that has ADO.NET capability. That includes a lot of open source RDBMS like PostgreSQL and MySQL, file systems, object oriented databases, and lots more. What’s even more interesting is that it is possible to build synchronization solution across different datastore types - for instance between PostgreSQL and SQL Server, or access and MySQL. This makes the framework extremely powerful.

    In this article, I will stick to using the Sync Framework for building a simple client-server synchronization for non-SQL Server database, PostgreSQL. The technique can be easily extended to any other database, like Oracle, MySQL, DB2, etc, but each database will require its own flavor of customizations depending on supported data-types, procedural language syntax and other things.

    This solution is based on an old sample provided by Microsoft for utilizing Sync Framework - since in SQL Server 2005 there was no in-built change tracking mechanism, this sample provided simple client-server architecture we could use. This original SQL Server version can be downloaded here .

    (The version shows as deprecated because SQL Server 2008 has its own change tracking mechanism; however for non-MS databases like MySQL or PostgreSQL, this sample is still very useful)

    I have adapted this to work with PostgreSQL. You can download the modified sample from here: Download .

    First, let us understand the Synchronization architecture for a simple client-server deployment - the server is the central repository of data, the client needs to have a local cache or copy of the server data (either full or partial) - this is based on three premises:

    1. There is a change tracking mechanism present in both the client and server databases- anchor values to track last time synchronization happened (in each client), timestamp columns and tombstone tables. These can be used to get new inserts/updates/deletes after the last anchor value was set.
    2. Each datastore is accessed using a SyncProvider in the sync application. The SyncProvider defines all the methods required to access the change tracking mechanism of the datastore.
    3. A SyncAgent or a SyncOrchestrator co-ordinates synchronization between the two SyncProviders and also takes care of conflict handling. We will be using a SyncAgent in our example.
    The change tracking mechanism

    The change tracking almost invariably happens through a combination of triggers and timestamp columns - for instance triggers to store lastupdatetimestamp on updates and to keep a record of deleted data and deletion timestamp in a tombstone table. There will then be a set of functions (Stored procedures, if you come from SQL Server background) required to get the incremental inserts, updates and deletes from the last set anchor, a function to get the new anchor value (generally the current timestamp) and a function to apply inserts, updates and deletes from the other datastore to this datastore.

    For a simple change tracking mechanism, the following objects will be required for each db table that is present in your database. The sample project attached will give an example of how each of these objects can look in a postgresql database.

    A tombstone table:

    And create, update and delete triggers

    The last two are required to get conflict data so that it can be taken up for conflict resolution in the sync logic.

    An anchor table is required at the database level, to hold sync anchors. This is required only in the client database and not in the server.

    And couple of more functions to retrieve the last sent and received anchor values

    The anchor table in the client database has one row for each of the data tables that are being synced. There are three columns - table name, last received anchor and last sent anchor. The received and sent anchors hold the information about when was the last data received from server and sent to server respectively. These are then used to get only incremental changes after this time both from the server and the client.

    The sent anchor will be the timestamp value from the client database and the received anchor will be the timestamp value from the server database. This is a small thing, but it makes a difference if there is a time difference between the machines hosting the server and the client.


    The actual synchronization is handled by the SyncEngine and the Sync providers. The sync providers handle the retrieval and applying of sync data from the particular implementation of the database and abstracts the framework logic from the database implementation. This is the reason, that for Sync Framework to work on postgresql database, all you need is a syncprovider that is customized to work with it.

    In the attached sample, PostgreSQLClientSyncProvider is one such provider. It inherits ClientSyncProvider, and connects the client PGsql database to the main sync application. The other provider used in DBServerSyncProvider - this connects the server database to the sync application.

    SyncEngine and SyncAgent

    SyncEngine initializes the syncproviders and the syncagent to initiate the synchronization. The Sync agent orchestrates the flow of data between the two SyncProviders. While initializing the SyncProviders, the SyncEngine also feeds database schema information to the SyncProviders through SyncAdapters (one syncadapter for each table) and provides the necessary get-incremental and apply commands that the providers need.

    One question would be how does the syncagent know what data is to be passed as parameter values when the apply commands are processed. This is simple - all the data retrieved from the incremental commands are stored in the sync session as datatables. Whenever the Sync Framework comes across a parameter, it tries to search within the sync session to see whether a similar named column exists in the sync session for the same table name. If it does, it matches it and uses that for as values for the corresponding parameters. This is why the parameter names in applys and the column names in select incrementals should match. You can try it out if you want - if you change the parameter names or give aliases to the columns in the select-incremental sps, then the synchronization won’t work as expected.

    Now that we have covered the concepts, it is time to dig into the actual code:

    First we have replaced all the SqlCommand, SqlTransaction and SqlParameter objects with NpgsqlCommand, NpgsqlTransaction and NpgsqlParameter objects. For this you need a reference to the Npgsql dll that can be downloaded from here .

    For this example, we have taken only one table - orders. Order_id is supposed to be the primary key and hence it has to be unique.

    To ensure that even in disconnected mode this id remains unique, we have used sequences starting from different values in the client and the server database. This design helps to ensure that we don’t have to worry about too many insert conflicts. The pkey sequences will be totally different for both client and server. To have a sizeable range, we are defining this column as bigint.

    The anchor value is another tricky thing to consider - this is generally serialized after retrieving and deserialized before setting. Since the datatypes used in SQL Server for this are not available in Postgresql, we need a slightly different strategy. Here I am using timestamp converted into bigint as the anchor values.

    This gives two advantages - since the bigint values can be easily compared with each other, it keeps our stored procedures simple. Also since this datatype is supported by Npgsql, it becomes very easy to retrieve this into our sync logic.

    All the procedures that are defined are self-explanatory and with the above concepts, you will understand them very easily. These stored procedures are then used in both the client and server sync providers and synchronization is called.

    To run the sample application,

    1. Prepare the databases - create two databases using the client and server scripts.
    2. Download and install Sync framework
    3. Open the solution PostgreSQLProviderSample.sln
    4. Modify the line 80 and 87 in the SyncEngine.cs file to point the connection strings to the above databases
    5. Run the code in debug mode
    6. Click on the "Make Random Insert" button by pointing to both the server and the client databases to create random rows.
    7. Click on synchronize to synchronize the rows.
    8. Try random updates and deletes too and then synchronize to see how the changes flow from client to server and vice-versa.

    If you notice the ids of the rows generated in server and client, you will notice that they are from entire different series. This is by design - without this, if inserts happen in client as well as server, then the chances of conflicts happening in your database are much more and it unnecessarily increases the complexity of the synchronization mechanism. Another way to achieve this is by using a GUID column but that can have some performance implications.

    So there you have it - a sample application that utilizes Microsoft Sync Framework to synchronize data across two Postgresql databases! Try it out and let me know what you think!

    Ms sync:

  • скачать
  • скачать
  • Другие статьи, обзоры программ, новости

    Introducing the Microsoft Sync Framework: Next Generation Synchronization Framework

    Khosravy, Moe

    Moe is the Lead Program Manager on the Microsoft Sync Framework and has been with the project since incubation. You can find him roaming the halls of campus preaching content flow and applying quotes from The Simpsons to everyday life. He was previously an architect in the Advanced Technologies group for Vital Images Inc, working on advanced medical visualization and analysis software solutions.

    This article was filed under:


    The Microsoft® Sync Framework is the new framework and runtime for adding synchronization, roaming, and offline capabilities to applications.

    It supports peer-to-peer scenarios, works with devices and services, and is agnostic of data types, stores, and protocols. In this article, I’ll cover the high-level vision for the platform as well as the enabled scenarios made possible by the framework for developers, ISVs, and OEMs.

    Several years ago, Microsoft assembled architects and researchers from across the company to understand the limitations preventing the seamless flow of data across applications, devices, and services to allow consumers access to their data wherever they need it. Throughout the investigations, several observations quickly emerged:

    • Lack of generic synchronization technology lead to the creation of numerous single-purpose solutions.
    • Solutions tended to reinvent the wheel; often falling into the same pitfalls explored by others.
    • Solutions could not be bridged as they made contradictory assumptions about the synchronization methodology (i.e. relied too heavily on specific topologies, data types, stores or business logic).

    It became clear that the only way to make progress towards enabling seamless “content flow” was to build a common framework with the following attributes:

    • Powerful. Able to solve the numerous hard problems related to interoperability.
    • Flexible. Able to be used in all endpoints in the sync-enabled ecosystem.
    • Simple. Easy to use in any architecture to compose new systems.

    Only then could the framework support roaming and sharing scenarios for content such as PIM, audio, video, settings, and files/folders across any number of PCs, services, and devices-all directly via peer-to-peer sync or through any number of intermediaries such as PCs or services.

    At the same time, more and more applications were looking to enable an Outlook-like cached mode of operation in which an application operates offline and periodically synchronizes with the server. Clearly, the common framework would need to excel at scenarios such as:

    • Caching and line of business (LOB) applications that can take data from relational databases and disparate back-end services offline.
    • Taking Web services and Web applications offline, providing richer experiences or simply network resiliency.
    Project Goals

    The Microsoft Sync Framework was created with the following goals in mind:

    1. Provide a common runtime for developers building synchronization solutions, allowing them to reuse a reliable and optimized code base capable of addressing the numerous subtle issues that developers run into when building caching, offline, sharing or roaming scenarios.
    2. Facilitate content flow across solutions, even if they utilize different protocols and stores by standardizing on the synchronization metadata.
    3. Simplify the actual development of sync solutions by providing domain-specific and end-to-end components for common scenarios such as syncing relational databases, file systems, lists, devices, PIM, music, video, etc…
    The Microsoft Sync Framework Approach

    A key tenet of the Microsoft Sync Framework is to bring existing applications and devices into the sync ecosystem by leveraging as much as possible from their existing implementations. This meant supporting synchronization between data stores ranging from large distributed Web stores backed by relational databases down to the file systems found on removable USB drives.

    The framework would also have to support numerous data types and schemas (such as relational data or files), as well as various sync topologies (such as peer-to-peer meshes or hub-and-spoke). These requirements emerged prominently whenever multiple sync solutions were bridged in a heterogeneous mesh.

    For these reasons the heart of the Microsoft Sync Framework consists of the common synchronization metadata model. By agreeing on only the metadata without forcing agreement on protocols or storage, the Microsoft Sync Framework lays the foundation for content-flow as well as a generic solution for synchronization, roaming, and sharing.

    The metadata at the core of Microsoft Sync Framework is highly efficient and compact, yet it provides full support for correct multi-master synchronization (that is, allowing concurrent updates on multiple endpoints). The Microsoft Sync Framework runtime implements the algorithms required to work with the metadata, allowing endpoints to easily participate in the ecosystem.

    To make it easier and more productive for developers building on Microsoft technologies to leverage these capabilities, Microsoft has started integrating the enabling technology into our next-generation flagships and platforms. For more information on Sync Services for ADO.NET and for an example of a Microsoft Sync Framework-enabled solution for rich synchronization and caching of relational databases, please see Steve Lasker’s article, Caching with SQL Server Compact and the Microsoft Sync Framework for ADO.NET in this issue of CoDe Focus .

    Components of the Microsoft Sync Framework

    The synchronization framework team designed the Microsoft Sync Framework as a componentized and layered architecture to allow developers to pick and choose only what they require to enable their scenarios and ensure that assets built on the framework could participate in the content flow ecosystem we’re working to grow.

    Microsoft designed the Microsoft Sync Framework as a componentized and layered architecture to allow developers to pick and choose only what they require to enable their scenarios and ensure that assets built on the framework could participate in the content flow ecosystem we’re working to grow.

    The Microsoft Sync Framework’s designers divided these components into the following logical layers, which are available to both managed and native code developers. (Note: Device builds for ARM, SH, x86, MIPS as well as Apple Mac support are in development and will be provided in a future CTP on MSDN).

    • Core Sync Runtime. Infrastructure that includes the algorithms to utilize the metadata as well as components to drive roaming, sharing, offline, and sync on behalf of applications.
    • Sync Provider Framework. Components designed to make it easier to expose data to the platform. This is effectively the plug-in model to the Microsoft Sync Framework by which developers can either configure existing Sync Providers or write their own.
    • Domain-specific components. Infrastructure to facilitate the rapid development of end-to-end solutions involving specific stores such as SQL Server, SQL Server Compact, FAT, NTFS, etc.
    Core Sync Runtime

    The core runtime contains the metadata services used by all of the Microsoft Sync Framework clients. Some of the features include:

    • Multi-master metadata representation and management, including conflict detection, custom and preset conflict resolution handling, change enumeration assistance, etc.
    • Conflict preservation management and representation of conflict resolution.
    • Support for change units (tracking changes at a property level) and consistency units (dealing with logical groupings of objects).
    • Handling of filtering changes and filter sync (both for items and for parts of items).
    • Recovery from a multitude of failure scenarios, such as tombstone cleanup, interruptions, network failures, etc.
    • Synchronization session management, such as cancellation, progress reporting, etc.

    The Microsoft Sync Framework provides an out-of-the-box Synchronization Agent that can synchronize endpoints when requested. The endpoints are abstracted using the notion of a Sync Provider, which is responsible for exposing the capabilities of a given endpoint, store or protocol. Applications use Sync Providers for the stores they need to synchronize and developers use the Microsoft Sync Framework to create custom Sync Providers for virtually any type of data.

    Core to the framework is support for Simple Sharing Extensions (SSE ). The Microsoft Sync Framework natively supports endpoints that wish to interoperate using SSE extensions for RSS and ATOM feeds. Furthermore, the framework provides services for feed generation and consumption, including the requisite conflict detection and preservation. While the Microsoft Sync Framework offers RSS/ATOM support out-of-the-box, developers can extend this support to other formats as well. High level producer/consumer APIs help easily turn any “Microsoft Sync Framework” provider into an SSE-enabled endpoint!

    Sync Provider Framework

    The Microsoft Sync Framework supports several ways of writing Sync Providers. Each is intended to make the experience as easy and efficient as possible. In addition to full-featured (that is, “full participant”) providers that are capable of true peer-to-peer sync, the framework provides support for allowing legacy and existing devices and applications to participate in the content flow ecosystem. Specifically, the Microsoft Sync Framework Sync Providers support the following scenarios:

    • Partial Participants. Providers that simply store but do not understand most of the sync metadata (e.g. a USB keychain, legacy phone, media device). Despite being very easy to develop even on endpoints that do not host the Microsoft Sync Framework engine, these providers can participate in all multi-master content flow scenarios.
    • Simple Participants. Endpoints that lack the ability to detect changes and that lack the ability to store metadata. The Microsoft Sync Framework has services to allow data from these participants to flow within the ecosystem on behalf of a fully featured participant/provider.
    • Anchor-Based Providers. Support for providers that rely on a simple tick-count based enumeration mechanism for their change detection mechanism (e.g. timestamps, tick counts, etc.).
    Storage Specific Components

    In addition to the Microsoft Sync Framework-enabled Sync Providers in development across Microsoft, the Microsoft Sync Framework includes several components to simplify the development of offline, sync, sharing, and roaming scenarios using specific stores and protocols. These components include:

    • Relational Data Providers. Synchronization Services for ADO.NET 2.0, the next version of Sync Services discussed in Steve Lasker’s article, (“Caching with SQL Server Compact and Sync Services for ADO.NET” in this issue of CoDe Focus ) will ship with SQL Server 2008. Sync Services 2.0 is built on the Microsoft Sync Framework aligning these two evolving sync platforms. It continues to dramatically simplify the caching of a remote or local database for scenarios such as line of business and branch office/point-of-sale scenarios, while providing peer-to-peer and other advanced sync capabilities. These providers take full advantage of the new change-tracking features in SQL Server 2008 and SQL Server Compact.
    • SQL Server Compact Metadata Store. A ready-to-use component for storing sync metadata such as versions, anchors, and change detection information. This component greatly simplifies the development of custom providers that do not have a natural place to store metadata.
    • File and Folder Sync Provider. A ready-to-configure provider capable of representing any Win32-compatible file system (e.g. FAT, NTFS, removable device). This provider handles challenges such as change detection on FAT volumes (including move and rename heuristics), name-name collision resolution, update-delete conflicts (including hierarchical update-delete), and the ability to preview a synchronization action.
    • ADO.NET Data Services Offline Provider. ADO.NET Data Services providers are currently being explored through prototypes that allow synchronizing data using REST-style interfaces for taking data services offline.
    • Plus many more providers currently in development across Microsoft!
    Sync-Enabled Content Flow Scenarios

    By removing the requirement that endpoints need intimate knowledge of one another in order to share or roam data, the Microsoft Sync Framework creates a sync-enabled occasionally connected ecosystem capable of providing:

    • Offline support for rich Internet applications. Ability to take a Web service or an Internet application offline with all changes synced back to any other endpoint without conflicts.
    • Calendar, Contact, Task List sync. Support for field-level sync such as “first name,” “last name” in an item-enabled rich PIM sync scenario.
    • Rich media sync. Ability to efficiently sync a full media library, or smaller subset, to the cloud or to devices either directly from another endpoint or through intermediaries. Ability to sync properties such as ratings and play count without transferring the entire media file.
    • Easy caching. The ability to easily cache a subset of the information from a remote or local store to support offline scenarios.
    • Sharing. Ability to have endpoints, such as devices, share data between any number of devices, clients, and services with edits possible at any node. This makes tethered or over-the-air sharing or roaming of media, PIM, files, and settings a breeze.

    While this is an introductory, high-level overview of the Microsoft Sync Framework CTP1, you’ll find plenty of material including “How-to” documents, full-featured samples, articles, and white papers as we unveil the framework on MSDN and at conferences in North America and Europe.

    Please visit http://msdn.microsoft.com/sync to get a copy of the Microsoft Sync Framework CTP1 SDK! I’m personally looking forward to reading your comments and feedback as we extend the framework and deliver on the content flow vision and strategy. I encourage developers to evaluate the SDK and request the features and improvements that will help you become more productive and the platform easier to use. We can be reached at syncsdk@microsoft.com and look forward to your feedback!

    Data Platform Team

    Sam Druker

    “I think we’re moving to the point that the cloud is becoming the next great platform for people to build applications on.”

    Sam currently leads the Data Programmability team at Microsoft, in the SQL Server division; Sam is responsible for building out the data platform development strategy and engineering, shipping XML and Data platform technology in the .NET Framework and throughout the SQL Server product line. Sam is also responsible for core XML and Data access components in the Windows platform, Internet Explorer, and Office.

    Sam has been in the software industry for more than 18 years. Prior to joining Microsoft, Sam was Vice President Engineering for LinkExchange, an early provider of Internet marketing services acquired by Microsoft in 1998 and Vice President Engineering for Cygnus Solutions, a provider of compiler and development tools to the open source community, since acquired by Red Hat Software. In the early nineties, he was a Principal Software Engineer at Cognex Corporation, a leading manufacturer of machine vision systems for factory automation and robotics. Sam started his software engineering career as Vice President Engineering for Zortech, which shipped the first native code compiler for C++. Sam is a graduate of MIT's VI-3 EECS program, a former offensive lineman for the Engineers, and now lives in Seattle, WA.

    Khosravy, Moe

    Moe is the Lead Program Manager on the Microsoft Sync Framework and has been with the project since incubation. You can find him roaming the halls of campus preaching content flow and applying quotes from The Simpsons to everyday life. He was previously an architect in the Advanced Technologies group for Vital Images Inc, working on advanced medical visualization and analysis software solutions.

    Why Microsoft lost Ford Sync: Too costly, too slow, and too hard to use

    Why Microsoft lost Ford Sync: Too costly, too slow, and too hard to use
    • By Bill Howard on February 24, 2014 at 4:09 pm Comment
    Share This article

    Ford is calling off the car connectivity relationship with Microsoft that produced Ford Sync. Ford instead will partner with Blackberry and use its QNX operating system. Worse for Microsoft, it’s possible other auto companies might bail on the company in the future. These automakers are looking for a technology partner that is able to lower their costs, improve performance and reliability, and get more third-party apps into the dash, and Microsoft hasn’t been pulling its weight.

    Microsoft is far from dead in the water — the software giant counts more than a dozen automakers as clients and we understand that several are happy customers. Bing is picking up support in the dash in response to a power play by Google that may have backfired. And even when Ford pulls the plug, there’s still a decade of revenues coming from Ford because of the need to support and update legacy systems until end-of-life (currently about 11 years). About 7 million Ford and Lincoln Sync cars are on the road.

    “Industry’s worst-kept secret”

    Here’s what’s happening, according to industry sources, none of whom want to be quoted because Detroit and Silicon Valley love gossip but not gossipers. In 2008, Ford thought it had a winner when it became the first automaker in the US to work with Microsoft for an in-dash infotainment solution providing Bluetooth, USB, voice recognition, a touchscreen interface, and optionally navigation. It shipped first on the 2008 Ford Focus and underwent continual improvement since then, in response to continual griping. Fiat introduced a similar Microsoft product, Blue&Me, a year earlier in Europe.

    Ford tried to improve Sync, and leaned on Microsoft to improve the back end, but the improvements apparently weren’t enough, especially as other automakers brought out systems that owners liked better (some ironically using Microsoft software in the background). Rising expectations for functionality rose faster than Ford could make improvements. Satisfaction ratings fell. Some say Microsoft got the basics right — Bluetooth, voice input — but never got past that plateau of core functionality. As a result, Ford will switch from Microsoft to RIM’s QNX. The deal hasn’t been announced but it has also been described as “industry’s worst-kept secret.”

    Ford could choose to continue, modify, or abandon the MyFord Touch interface. Sync is the car-Bluetooth-USB-voice recognition component. MyFord Touch and the similar MyLincoln Touch are touchscreen interfaces that break the home screen into four quadrants: phone, navigation, entertainment, and climate control. (It’s possible to have Sync without a touchscreen.) Separate from Ford’s plans to move away from Microsoft, it is planning to add more knob and buttons to the center stack and simplify voice response. Lincoln on new models will move from capacitive sliders to traditional knobs for audio volume and fan speed. That starts on some 2015 models.

    Clobbered by J.D. Power and Consumer Reports

    Four in ten buyers say in-car technology is the main reason for buying a car, according to an Accenture report. Ford cites numbers that Sync is a key reason why buyers shop Ford and Lincoln. Some customers feel differently after purchase. The annual J.D. Power Initial Quality Survey ranked Ford No. 27 of 33 brands. Lincoln matched the industry average and was ranked No. 17. IQS measures problems per 100 (PP100) vehicles in the first 90 days of ownership.

    IQS used to mean things that broke but now it also includes subjective, touchy-feely issues such as brake dust, road noise, size of dashboard buttons, or ease of using a touchscreen. Consumer Reports last October ranked Ford and Lincoln Nos. 26 and 27 on reliability. Its survey includes more than just broken mechanical systems in the results.

    C# - Microsoft Sync Framework for file and database - HintDesk

    C# – Microsoft Sync Framework for file and database

    Data synchronization is always a top feature for any product in IT zone, especially if your product is a database-based product. It provides the customers more flexibilities and “freedom” when using the products. For example, the customer is on construction area, enter data through a concise mini mobile client, then sync them with server and when they are back to office, they have all data in the main software and finish the rest of work. That means at anytime and anywhere they can access their updated data. However it’s not easy at all to implement this dreaming feature in any application because of the complexity. However if you’re using Microsoft products, you can easily build this feature in your apps thanks to Microsoft Sync Framework (MSF) http://msdn.microsoft.com/en-us/sync/bb736753. Maybe you’ll say that there is already the replication feature in MS SQL Server, why do you need to use MSF? Yes, it’s correct that MS SQL has already this feature but obviously we can only sync between MS SQL Servers. How about if we want to sync between MS SQL Express? The answer can be MSF.

    In this small blog, I would like to make a small introduction about MSF through an example showing how we can simply sync 2 databases in MS SQL Express. It’s very simple example so that you have a good start with MSF, don’t expect for something advanced here. If you are already professional with MSF, you can skip this blog. First you need to download Microsoft Sync Framework Software Development Kit with latest version of 2.1 at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=23217 and install it. In MS SQL Express, create a new database called “MainDb” with 2 tables “Orders” and “OrdersDetails”. The scripts for creating tables are below

    Execute this SQL statement several times to insert some data records into tables

    Now create another new database call “ClientDb01” and let it clear, we’ll sync it with the master database.

    Now start Visual Studio, create a new Console Application and add references to .dll of MSF. The .dll can be found in .NET reference tab.

    Then write the listing below to make synchronization between them.

    As you can see that the main object which is responsible for synchronizing between databases is SyncOrchestrator which needs two providers: LocalProvider and RemoteProvider. These providers can be FileSyncProvider, SqlSyncProvider or any custom provider depending on which object we would like to synchronize. In case of SqlSyncProvider, we can declare SyncProvider with a scope name and its connection. In case of FileSyncProvider, we need path to folders we would like to synchronize like this

    We can apply more settings to the SyncProvider through SqlSyncScopeProvisioning to customize the synchronization. In the example, I define which tables should be synchronized between databases. The result of synchronizing process will be stored in SyncOperationStatistics telling how many data record was sent to remote server or download from it and if any record can’t be synchronized. So now if I execute the code, I’ll receive the statistic at frontend and at backend the contents of both databases are same.

    As you can see, MSF create some metadata tables for controlling the synchronization too. It makes the databases a little complicated and messy but I think for an administrator it’s no problem. Now I would like to make a small test to see what will happen when changes occur at both of sides: local and remote. Therefore I open the OrderDetails table of MainDb, insert one data record and open OrderDetails of ClientDb01, insert one other data record. The content of these records are different.

    Then I let the synchronization sync again, that result really satisfies me. Both of tables has exactly same structure of data (please notify the Id of each data record of table OrderDetails).

    Ok, MSF passed first test with data integrity. Now I would like to make a second test for duplication, what would happen if changes from local and remote are same? I open OrderDetails table of MainDb and ClientDb01 again and insert another data record to them, but these records are same. I let the synchronization again, the statistic shows that there are some data to be uploaded and downloaded. But when opening the table at back end, we’ll see that there are no changes in database. MSF recognizes that they are duplicated and don’t insert them again into database.

    MSF is a powerful framework. We can use it to sync any object with our custom sync provider. It allows us to define how the synchronization should run and how it should behave for any conflict. I hope that you have a good start with MSF and maybe I’ll write some more articles about this wonderful framework. At usual is source code for anyone who is interested in “Sync Framework Basic Example “

    Microsoft Sync Framework

    Microsoft Sync Framework

    Microsoft Sync Framework представляет собой многофункциональную платформу синхронизации, которая обеспечивает совместный и автономный доступ для приложений, служб и устройств. Она содержит технологии и средства, позволяющие выполнять перемещение, общий доступ и получение данных в автономном режиме. При помощи Sync Framework разработчики могут создавать экосистемы синхронизации, которые позволяют интегрировать любое приложение с любыми данными из любого хранилища, использующего любой протокол в любой сети.

    Платформа Sync Framework включает следующие решения, из которых первые три можно установить вместе с SQL Server 2008.

    Службы Sync Services for ADO.NET можно использовать для автономной и общей синхронизации баз данных.

    Базовые компоненты Sync Framework могут использоваться службами Sync Services for ADO.NET для синхронизации баз данных и создания поставщиков синхронизации для других типов хранилищ данных.

    Службы Sync Services for FeedSync можно использовать для синхронизации RSS- и Atom-потоков в локальном хранилище.

    Службы Sync Services for File Systems можно использовать для синхронизации файлов и папок в файловой системе.

    Служба хранилища метаданных позволяет хранить метаданные синхронизации в SQL Server Compact 3.5.

    Оставшаяся часть этого раздела содержит общие сведения о службах Sync Services for ADO.NET и сравнение с другими технологиями Майкрософт. Полную документацию по Sync Services for ADO.NET и Sync Framework см. в Центре разработки Microsoft Sync Framework.

    Microsoft Sync Framework

    Microsoft Sync Framework Общие концепции

    Microsoft Sync Framework (MSF) – это платформа для разработки решений, реализующих различные сценарии синхронизации, появившаяся в SQL Server 2008.

    Архитектура Sync Framework позволяет обмениваться данными любому количеству устройств, сервисов и экземпляров приложений, рассматривая хранилища данных, механизмы передачи и схемы как стандартные блоки. Синхронизируемые хранилища данных в терминологии Sync Framework называются копиями данных (или репликами; в данной статье они будут называться копиями данных или просто копиями). Блоки Sync Framework – это рантайм, сервисы метаданных и провайдеры. Рантайм производит синхронизацию копий данных согласно указаниям провайдеров. Провайдеры используют сервисы метаданных для обработки и хранения метаданных.

    На рисунке 1 показана применяемая в Sync Framework схема организации синхронизации. Синхронизацию выполняет объект сессии синхронизации, используя интерфейсы провайдеров хранилищ данных. Например, если нужно синхронизировать контакты между мобильным устройством и хранилищем данных, создается сессия синхронизации, соединяющая провайдеров этих устройств, и определяющая наличие изменений, используя сервисы метаданных.

    Рисунок 1.

    Участники синхронизации

    Участник синхронизации – это комбинация провайдера и ассоциированной с ним копии данных.

    MSF поддерживает три типа участников синхронизации: полный, частичный и простой. Тип участника определяется его способностью сохранять и обрабатывать метаданные.

    Полные участники

    Полные участники – это способные хранить данные устройства, для которых можно разрабатывать приложения. Примерами таких устройств могут быть ноутбуки или смартфоны, способные самостоятельно исполнять приложения, а также сохранять необходимые для синхронизации данные.

    Частичные участники

    Частичные участники – это устройства, способные хранить данные, но неспособные исполнять приложения. Важно то, что они могут хранить метаданные синхронизации, что позволяет синхронизировать их с любым полным участником. Примером такого устройства может быть флешка или MP3-плейер.

    Простые участники

    Простые участники – это устройства, способные только выдавать информацию по запросу. Они неспособны сохранять новые данные и манипулировать ими, и не поддерживают создания новых приложений. Простой участник в хранении метаданных полагается на полного участника.

    Примерами простых участников могут служить Web-сервисы сторонних организаций. Вы можете обращаться к этим Web-сервисам и получать результаты, но возможности создать собственное хранилище данных или выполнить свое приложение они вам не предоставят.

    Состав Microsoft Sync Framework

    Microsoft Sync Framework включает:

    • Ядро Sync Framework, которое используется для создания провайдеров синхронизации хранилищ данных любого типа.
    • Microsoft Sync Services for ADO.NET, предназначенные для синхронизации баз данных.
    • Sync Services for File Systems. службы для синхронизации файлов и папок файловой системы.
    • Sync Services for FeedSync, служба для синхронизации RSS- и Atom-лент с данными в локальных хранилищах.
    • Metadata Storage Service – служба для хранения метаданных синхронизации в SQL Server Compact Edition.

    MSF предоставляет разработчикам приложений синхронизации:

    • Рантайм ядра синхронизации, предоставляющий универсальную функциональность, не зависящую от протоколов и типов данных.
    • Компоненты для быстрой разработки решений синхронизации на платформах Microsoft SQL Server 2008, Microsoft Visual Studio 2008, для файловых систем FAT и NTFS, а также для съемных носителей.
    • Модель провайдера, интегрирующую источники данных в систему синхронизации.
    • Средства автоматического или ручного разрешения конфликтов синхронизации.
    • Возможность создания и использования FeedSync-совместимых потоков данных.
    • Встроенную поддержку фильтров для синхронизации таких коллекций данных, как почтовые ящики или медиа-библиотеки.

    Метаданные – основа Microsoft Sync Framework, как и любого другого продукта для синхронизации данных. Отслеживание изменений основывается в MSF реализуется простым сравнением текущего состояния данных с ранее сохраненным состоянием. Для каждой синхронизируемой копии или элемента данных должен существовать определенный набор метаданных.

    MSF разрешает использовать любой формат метаданных. Тем не менее, существуют рекомендации по формату метаданных, приведенные ниже.

    Сведения (knowledge)

    Такие типичные операции синхронизации, как перечисление изменений и выявление конфликтов, требуют сравнения версий элементов синхронизируемых копий данных. Для этого придется передать копии назначения все версии элементов копии-источника. Это очень неэффективно.

    В целях оптимизации было принято решение сжать все номера версий в одну компактную структуру данных, получившую название knowledge. или, по-русски, сведения. Эти сведения отражают все изменения (то есть содержат версии всех элементов), известные этой копии данных. Обычно сведения очень компактны. Однако они не могут полностью заменить метаданные элементов, поскольку по-прежнему нужно знать, когда и как изменялся тот или иной элемент.

    Сведения могут содержать следующие вхождения:

    1. Scope clock vector.
    2. Range exceptions.
    3. Single item или change unit exceptions.

    Scope clock vector определяет наиболее компактное представление сведений, при котором их размер пропорционален числу синхронизируемых копий. Scope clock vector состоит из элементов, которые называются clock vector elements. За всеми этими мудреными словами скрывается довольно простая вещь. Элемент – сочетание ключа копии данных и временной метки (в терминах MSF – tick count), определяющей версию элемента, а clock vector – это множество таких пар.

    Каждый clock vector содержит как минимум один элемент, соответствующий локальной копии. Поскольку разные копии имеют разные и уникальные ID, эти элементы тоже являются уникальными для каждой копии.

    Range exceptions используются для ассоциирования clock vector с диапазонами элементов, т.е. для элементов копии, имеющих значения ID, попадающие в указанный интервал, сведения будут иметь значения, равные clock vector-у range exception-а. Как несложно представить, range exceptions уменьшают объем структуры сведений, поскольку обычно указывают clock vector сразу для многих синхронизируемых элементов.

    Single item exceptions используются для ассоциирования clock vector-а с одним элементом или единичным изменением. Это наименее компактное представление сведений, используемое только если невозможно использовать другие

    Если жизнь хороша, и никаких конфликтов, ошибок или прерываний синхронизации нет, сведения остаются компактными и содержат только scope clock vector. В противном случае сведения становятся фрагментированными, в них появляются range exceptions и single item exceptions. Эти исключения указывают на отклонения от scope clock vector для конкретных элементов, единичных изменений или диапазонов элементов. Заметьте, что эти исключения не постоянны и исчезают после удачной синхронизации или разрешения конфликта.

    Идентификаторы копий и элементов

    Идентификаторы копий и элементов могут иметь как фиксированную, так и переменную длину. ID фиксированной длины представляются в виде байтового массива, а переменной – классом SyncId в управляемом, и структурой SYNC_ID – в неуправляемом коде.

    Класс SyncIdFormatGroup в управляемом коде и структура ID_PARAMETERS в неуправляемом содержат схему формата ID. Эта схема говорит, имеет ли ID фиксированную или переменную длину, а также содержит размер ID, или, в случае переменной длины, максимальный размер ID. Эта схема используется многими методами MSF для проверки соответствия форматов ID, используемых разными синхронизируемыми объектами. Схема запрашивается у обоих провайдеров, участвующих в сессии синхронизации. Полученные схемы сравниваются, и, если они не совпадают, сессия не создается.

    При синхронизации иерархических данных может оказаться полезным использовать в качестве префикса ID увеличивающееся число, например, текущее время. Поскольку родительские элементы обычно создаются раньше потомков, они будут встречаться в списке элементов раньше.

    Создаваемым элементам можно присваивать глобальные идентификаторы, используя тот же способ, независимо от их контейнеров или вложенных элементов.

    Обязательные метаданные копии

    Каждая копия данных должна хранить некоторый обязательный набор метаданных, описанный ниже.

    Уникальный идентификатор копии данных. Это может быть любой идентификатор, но Microsoft рекомендует использовать 16-байтный GUID. Формат идентификатора копии, передаваемый методу MSF, должен соответствовать формату, определенному в провайдере. В управляемом коде формат указывается в свойстве IdFormats, а в неуправляемом – в структуре ID_PARAMETERS.

    Current tick count

    Текущий счетчик тиков копии. Это число можно получить от наиболее поздней локальной версии или еще каким-либо способом. Например, копия может использовать текущее время, если гарантируется, что его значение не будет сброшено.

    Отображение ключа копии (Replica key map)

    Отображение между ID копии и 4-байтными ключами. Из-за постоянных повторов идентификатора копии в метаданных рекомендуется использовать таблицу, в которой идентификаторы копий отображаются на 4-байтные ключи. Эти ключи впоследствии используются для ссылок на конкретные копии.

    Текущие сведения

    Сведения о текущих версиях элементов копии. С этими сведениями работают сервисы метаданных, лучше не трогать их руками.

    Забытые сведения (Forgotten knowledge)

    Позволяют копии определить, что копия-партнер не знает об удаленных элементах. Такое может случиться, если были удалены записи об этих элементах. Этими сведениями тоже должны оперировать сервисы метаданных.

    Журнал конфликтов

    Журнал с записями об обнаруженных, но не разрешенных конфликтах. Копии обязаны вести такие журналы. Форма представления конфликта зависит от вида хранилища данных. MSF должен иметь доступ к этим записям, чтобы сообщать пользователю о необходимости вмешательства в случае невозможности автоматического разрешения конфликта.

    Кладбищенская книга (Tombstone log)

    Информацию об удаленных из копии данных с черным юмором называют “tombstones”. На русский язык это переводится как «надгробие» или (велик и могуч английский язык) «длинный список участников проекта». Журнал, в котором перечислены такие надгробия, логично назвать кладбищенской книгой, или, вспоминая, что русский язык тоже велик и могуч, поминальничком. Этот журнал, как уже понятно, хранит информацию об элементах, удаленных из копии, что необходимо для распространения сведений об удалении среди всех синхронизируемых копий во избежание ошибочного воскрешения покойничков. Ведение такого журнала обязательно для каждой копии, форма записи зависит от вида хранилища данных. Такие дела.

    Однако периодически сведения из этого журнала приходится удалять, во избежание проблем с производительностью и напрасной траты места. После этого сеансы промышленной некромантии становятся вполне вероятными, так что следует относиться к подобным чисткам логов с надлежащей осторожностью. Скажем об этом несколько подробнее.

    Каждая копия содержит сведения только о собственном состоянии, и понятия не имеет о состоянии остальных. Определить, как широко распространились сведения о кончине того или иного элемента, невозможно. Поэтому как и когда очищать журнал удаленных элементов, остается полностью на совести разработчика. Например, можно устраивать регулярную, периодическую чистку, или ориентироваться по размеру журнала.

    После чистки копия больше не помнит об удаленных элементах, но по-прежнему должна не допускать их воскрешения путем копирования из других копий. В этом ей помогают «забытые сведения», сохраняемые в хранилище метаданных.

    Два основных сценария, использующих записи об удаленных элементах – синхронизация устаревшей копии и попытка обновления удаленного элемента.

    Выявление устаревшей копии

    В этом сценарии копия назначения очень давно не обновлялась, и ее требуется синхронизировать с копией-источником. Но копия-источник, идущая в ногу со временем, уже почистила лог и забыла обо всех удалениях. Ее провайдер ничего не может сказать по этому поводу провайдеру копии назначения. В полном соответствии с логикой процесса синхронизации провайдер копии назначения пришлет свои сведения провайдеру копии-источника и запросит изменения. В этот момент провайдер копии-источника должен сравнить полученные сведения с «забытыми сведениями» из хранилища метаданных. Если какой-либо элемент clock vector-а из «забытых сведений» больше соответствующего элемента clock vector-а из текущих сведений копии назначений, значит, копия-источник уже забыла о некоторых удалениях, о которых копия назначения еще не узнала.

    Чтобы выявить такую ситуацию, копия сохраняет сведения о забытых записях. До внесения изменений MSF проверяет эти сведения. Если обнаруживается устаревшая версия, автоматически запускается полное перечисление исходных элементов для применения к копии назначения.

    Если приложение зарегистрировало обработчик событий, Sync Framework даст приложению возможность продолжить или прервать полное обновление. В управляемом коде будет сгенерировано событие FullEnumerationNeeded, а в неуправляемом приложение получит вызов ISyncCallback::OnFullEnumerationNeeded.

    Если никакого обработчика не создано, автоматически будет выполнено полное обновление.

    Запрос обновления удаленного элемента

    Предположим, что исходная копия назначения не синхронизировалась с тех пор, как копия назначения в последний раз очистила сведения об удаленных элементах. Элемент был удален из копии назначения, и запись о его удалении тоже уже удалена. Этот же элемент в копии-источнике был обновлен. Таким образом, элемент появляется в списке изменений, который провайдер копии-источника посылает в ответ на запрос синхронизации от провайдера копии назначения. Провайдер копии назначения должен распознать, что этот элемент – не новый, иначе элемент будет ошибочно восстановлен в копии назначения.

    Текущую версию этого элемента в копии-источнике бесполезно сравнивать с текущими сведениями копии назначения – там об этом элементе ничего нет. Вместо этого со сведениями копии назначения нужно сравнивать версию создания элемента в копии-источнике, чтобы определить, что копия назначения когда-то знала об этом элементе. Поскольку удаление элемента заведомо произошло позже его создания, текущие сведения копии назначения должны содержать запись о создании элемента.

    Таким образом, перед созданием нового элемента в копии назначения MSF сравнивает версию создания элемента со сведениями копии назначения. Если там есть версия создания элемента, значит, такой элемент когда-то существовал, но уже был убит и забыт.

    Обязательные метаданные элементов копии

    Каждому синхронизируемому элементу тоже должен соответствовать обязательный набор метаданных.

    Глобальный ID

    Идентификатор элемента копии. Поскольку за генерирование глобальных ID отвечает копия, она может использовать эти ID для повышения эффективности работы с данными. Например, можно определить, что глобальный ID – это GUID с 8-байтным префиксом, то есть:

    Такой префикс можно использовать при сортировке идентификаторов, что облегчит провайдерам перечисление изменение в копиях. В управляемом коде формат определяется в свойстве IdFormats, а в неуправляемом – в структуре ID_PARAMETERS.

    Текущая версия

    Самая поздняя версия конкретного элемента. Эта версия сохраняется при каждом единичном изменении элемента, к которому применимы единичные изменения. Например, у контакта могут быть разные номера версий для полей адреса и номера телефона. Версия – это 12-байтный структурированный логический номер версии, состоящий из ключа копии, в последний раз обновлявшей элемент, и значения счетчика тиков этой копии.

    Версия создания

    Номер версии, присвоенный данному элементу при создании.

    Объем метаданных

    Поскольку формат глобальных ID определяет копия, объем сохраняемых метаданных может существенно различаться. Однако при соблюдении рекомендованного формата, использующего GUID и 8-байтный префикс, на хранение обязательных метаданных элемента требуется 48 байт – 24 байта на глобальный ID, и по 12 байт на номер версии и версию создания элемента.

    Ядро синхронизации MSF составляют сервисы для работы с метаданными, используемыми всеми компонентами MSF в процессе синхронизации. Эти сервисы предназначены для:

    • Управления метаданными.
    • Управления сессиями синхронизации.
    • Отслеживания изменений.
    • Обнаружения и разрешения конфликтов при синхронизации.
    • Работы с фильтрами.
    • Восстановления при сбоях.

    Эти компоненты освобождают приложения и провайдеры от необходимости вникать в детали работы с метаданными. Кроме того, ядро предоставляет средства работы с Metadata Storage Service, компонента, управляющего хранением метаданных.

    Metadata Storage Service

    Metadata Storage Service служит для сохранения метаданных синхронизации провайдерами, представляющими копии, неспособные делать это самостоятельно.

    Metadata Storage Service API четко разграничивает хранилище данных и интерфейсы и методы, используемые для доступа к хранилищу данных, что позволяет реализовать и использовать альтернативные хранилища, практически не изменяя провайдер.

    По умолчанию Metadata Storage Service использует для хранения метаданных Microsoft SQL Server Compact Edition. Он предоставляет методы для создания нового хранилища данных, работы с уже существующим хранилищем, инициализации метаданных копии, а также для явного управления транзакциями.

    Интерфейсы Metadata Storage Service однопоточны. Вызовы могут делаться из любого потока, но многопоточные приложения должны обеспечивать синхронизацию потоков для использования этих интерфейсов.

    Создание хранилища

    Хранилище данных в управляемом коде представляется объектом SqlCeMetadataStore, а в неуправляемом – интерфейсом ISqlCESyncMetadataStore.

    Для создания нового хранилища служит метод CreateStore.

    Если создано новое хранилище, метаданные копии нужно инициализировать, прежде чем использовать. Для этого служит метод InitializeReplicaMetadata. Этот метод вызывается для каждой БД только один раз. Поэтому, если нужно определить пользовательские поля, о которых сказано ниже, это должно быть сделано именно в этот момент.

    Данная реализация хранилища метаданных может хранить метаданные только одной копии.

    Для доступа к метаданным используется метод GetReplicaMetadata, создающий объект, представляющий метаданные копии. Metadata Storage Service защищает БД от параллельных изменений, позволяя создавать только один такой объект для каждого ID копии.

    Пользовательские поля

    Разработчик может определить свои поля для метаданных элементов копии. Это делается при помощи объекта FieldSchema (или структуры CUSTOM_FIELD_DEFINITION в неуправляемом коде). Для таких полей указывается имя, тип и размер, а также индексируются они или нет. Как уже говорилось, пользовательские поля определяются при инициализации метаданных копии. Доступ к ним, как и к другим метаданным элемента, производится через объект ItemMetadata (интерфейс IItemMetadata в неуправляемом коде)


    Транзакции могут выполняться явно или неявно. Обычно данные помещаются в БД следующим образом:

    • Значения свойств задаются через объекты ReplicaMetadata или ItemMetadata.
    • Значения сохраняются с помощью методов SaveReplicaMetadata или SaveItemMetadata этих объектов.

    На этот момент данные еще не записаны на диск. Выбор момента записи определяется типом используемой транзакции.

    Неявные транзакции

    Если при сохранении значений свойств не была явно начата транзакция, используется неявная транзакция, при которой данные могут быть сохранены либо когда SQL Server Compact Edition сбросит на диск все изменения, либо когда будет успешно завершен процесс приложения, сохраняющего изменения. В случае сбоя или непредвиденного завершения приложения нет никакой гарантии, что данные будут сохранены – такую гарантию может дать только явная транзакция.

    Явные транзакции

    Явные транзакции запускаются вызовом метода BeginTransaction, а изменения сохраняются вызовом CommitTransaction. Как несложно догадаться, для отката транзакции служит метод RollbackTransaction.

    Провайдеры синхронизации

    В Microsoft Sync Framework провайдер синхронизации – это программный компонент, позволяющий синхронизировать между собой различные копии данных. В сущности, каждый провайдер представляет копию данных, например, БД или папку файловой системы.

    Во время сессии синхронизации приложение, выполняющее синхронизацию, соединяет провайдера копии-источника данных с провайдером копии-приемника, и воспроизводит в приемнике изменения, накопившиеся в источнике. Например, провайдер для папки в файловой системе может быть связан с другим провайдером, отвечающим за аналогичную папку, для синхронизации файлов между этими папками. Для синхронизации приложение сначала создает объект сессии синхронизации, соединяет его с двумя объектами-провайдерами, после чего начинает сессию синхронизации.

    В процессе синхронизации провайдер приемника данных сообщает о своем текущем состоянии, принимает список изменений от источника, выявляет конфликты между этим списком и текущим состоянием подведомственной ему копии и применяет изменения к своему хранилищу данных.

    Провайдер источника данных использует информацию о состоянии приемника, чтобы выяснить, о каких изменениях в источнике еще не знает приемник, и отправляет список изменений провайдеру копии-приемника через метод GetChangeBatch.

    В состав MSF входят следующие провайдеры:

    • Microsoft Sync Services для ADO.NET, для синхронизации баз данных.
    • Sync Services для File Systems, для синхронизации файлов и папок файловой системы.
    • Sync Services для FeedSync, для синхронизации RSS- и Atom-лент с данными в локальных хранилищах.

    Microsoft Sync Framework позволяет также создавать собственные провайдеры синхронизации, но реально входящие провайдеры покрывают большую часть распространенных сценариев. Ниже будет рассмотрено создание простейшего провайдера синхронизации.

    Microsoft Sync Services для ADO.NET

    Microsoft слегка лукавит, говоря, что MSF служит для синхронизации чего угодно с чем угодно. Форд в свое время говорил, что автомобиль может быть любого цвета, при условии, что он черный. Так и Sync Services для ADO.NET могут синхронизировать любого клиента с любым сервером, при условии, что этот клиент – SQL Server Compact 3.5 SP1. Провайдеров для других клиентских СУБД, насколько мне известно, пока не существует. Можно надеяться, что они появятся в ближайшем будущем, но пока что никаких их следов найти не удалось.

    Впрочем, ничто не мешает разработчикам реализовать такие провайдеры самостоятельно. Пример создания провайдера синхронизации можно найти по адресу http://msdn2.microsoft.com/ru-ru/library/bb902809(en-us,SQL.100).aspx. Однако, поскольку в задачи этой статьи разработка провайдера для какой-либо СУБД не входит, рассмотрим работу Sync Services для ADO.NET на примере уже существующего провайдера.

    Sync Services поддерживают двухуровневую и многоуровневую архитектуры синхронизации с любым сервером БД, для которого существует ADO.NET-провайдер. Для синхронизации клиентской БД с другими источниками данных используется сервис-ориентированная архитектура. Такой подход требует больше кода, чем двухуровневая или многоуровневая архитектура, но принципы синхронизации остаются теми же самыми.

    Sync Services позволяют выполнять snapshot, download-only, upload-only и двунаправленную синхронизацию:

    • Snapshot и download-only синхронизация обычно используется при работе со справочниками (например, каталогом продуктов) на стороне клиента. Snapshot-синхронизация полностью обновляет все данные при каждом сеансе синхронизации. При download-only синхронизации с сервера скачиваются только элементы, изменившиеся со времени предыдущей синхронизации.
    • Upload-only синхронизация обычно используется для сохранения на сервере клиентских данных.
    • Двунаправленная синхронизация используется для данных, которые могут изменяться как на клиенте, так и на сервере. При использовании этого вида синхронизации необходимо отслеживание и обработка конфликтов.

    Архитектура Sync Services асимметрична. Это значит, что отслеживание изменений встроено в клиентскую БД, но на сервере это придется реализовать разработчику.

    На приведенных ниже рисунках показаны компоненты, используемые в двухуровневых, многоуровневых и сервис-ориентированных архитектурах. На рисунках показан только один клиент. Реально с каждым сервером, как правило, синхронизируется много клиентов. Sync Services используют модель hub-and-spoke (насколько мы понимаем это ничем не отличается от топологии «звезда», впрочем, мы можем и ошибаться – прим.ред.).

    Рисунок 2. Двухуровневая архитектура.

    Схема двухуровневой архитектуры синхронизации приведена на рисунке 2.

    Все элементы этой схемы, кроме, разумеется, двух БД, соответствуют классам Sync Services. Эти классы находятся в следующих DLL:

    • В Microsoft.Synchronization.Data.dll содержатся агент, таблицы и группы синхронизации.
    • Microsoft. Synchronization.Data.SqlServerCe.dll содержит клиентский провайдер синхронизации.
    • В Microsoft. Synchronization.Data.Server.dll лежит серверный провайдер и адаптеры синхронизации.

    Все эти библиотеки зависят от System.dll и System.Data.dll из .NET Framework 2.0 или более поздних версий. Microsoft.Synchronization.Data.SqlServerCe.dll также зависит от System.Data.SqlServerCe.dll из SQL Server Compact 3.5 SP1. В двухуровневых приложениях все библиотеки находятся на клиенте. В многоуровневых приложениях Microsoft.Synchronization.Data.dll и Microsoft.Synchronization.Data.Server.dll лежат в отдельном слое, реализующем сервис синхронизации, и, возможно, расположенном на отдельном компьютере.

    Рисунок 3. Многоуровневая архитектура.

    На рисунке 3 приведена схема многоуровневой архитектуры синхронизации. В ней для связи клиентской и серверной БД используются прокси, сервис и транспортный механизм. Такая архитектура применяется чаще, чем двухуровневая, поскольку не требует прямого соединения между клиентом и сервером.

    Рисунок 4. Сервис-ориентированная архитектура.

    На рисунке 4 показана сервис-ориентированная архитектура. Она включает клиентскую БД, но серверной БД и соответствующих ей адаптеров и провайдеров синхронизации в этой схеме нет. Вместо них приложение должно использовать сервис и прокси, предоставляющие функциональность провайдера и адаптеров, например, получение списков изменений.

    Элементам приведенных выше рисунков соответствуют классы SyncAgent, SqlCeClientSyncProvider, DbServerSyncProvider, SyncTable, SyncGroup и SyncAdapter.

    Агент синхронизации (SyncAgent)

    Агент синхронизации руководит синхронизацией. Обычно он находится на клиентской стороне и работает согласно запросам клиентского приложения. Агент традиционно для MSF работает с двумя провайдерами синхронизации.

    Таблица синхронизации (SyncTable) и группа синхронизации (SyncGroup)

    Таблица синхронизации определяется для каждой таблицы, синхронизируемую на клиенте. Она задает настройки, а также направление синхронизации: Snapshot, Download-only, Upload-only или двунаправленная.

    После создания таблицы синхронизации она может быть введена в группу синхронизации. Группа синхронизации – это механизм, обеспечивающий согласованную синхронизацию набора таблиц.

    Клиентский провайдер (SqlCeClientSyncProvider)

    В состав MSF входит ClientSyncProvider, клиентский провайдер синхронизации для SQL Server CE 3.5. Других провайдеров, как уже говорилось, пока что в составе поставки нет, что печально.

    Серверный провайдер (DbServerSyncProvider)

    Серверный провайдер служит для связи с серверной БД и скрывает работу с СУБД от агента синхронизации.

    В состав MSF входит серверный провайдер синхронизации DbServerSyncProvider, предназначенный для работы с реляционными СУБД, поддерживающими ADO.NET. Для каждой синхронизируемой таблицы создается объект SyncAdapter, описанный ниже, и содержащий команды для работы с БД. У провайдера также есть две собственные команды:

    • SelectNewAnchorCommand – серверный провайдер использует эту команду, чтобы получить новую метку синхронизации. Эта метка вместе с меткой, получаемой от клиента, определяют интервал для перечисления изменений.
    • SelectClientIdCommand – в случае двунаправленной синхронизации каждая строка должна хранить сведения о том, какой клиент последним изменял ее.

    SyncAdapter создан по образу и подобию DataAdapter-а ADO.NET, но работает с другими командами. Смысл многих из них понятен без объяснений, для остальных же приведем краткие пояснения:

    • InsertCommand, UpdateCommand, DeleteCommand понятны без объяснений, неясно только, зачем нужен довесок Command.
    • SelectIncrementalInsertsCommand – перечисляет вставки в серверную БД с момента последней синхронизации.
    • SelectIncrementalUpdatesCommand – перечисляет измененные записи.
    • SelectIncrementalDeletesCommand – перечисляет удаленные записи.
    • SelectConflictUpdatedRowsCommand – перечисляет записи, изменение или создание которых не удалось.
    • SelectConflictDeletedRowsCommand – перечисляет существующие сроки, которые не вышло изменить или удалить. Эта команда будет искать конфликтующие строки в tombstone-таблице.

    В SyncAdapter есть и другие команды, но далеко не факт, что все они вам понадобятся. Например, при реализации однонаправленного сценария потребуются только три SelectIncremental-команды. Больше того, для создания адаптеров «на лету» существует специальная приблуда SqlSyncAdapterBuilder.

    SqlSyncAdapterBuilder служит для создания кода команд синхронизации, исполняемых серверным провайдером. Он порождает SQL-выражения на основе информации о таблицах, участвующих в синхронизации. Для работы ему нужно указать следующее:

    • Сихронизируемые таблицы.
    • Отслеживаемые колонки таблиц.
    • Направление синхронизации.
    • Участвующие в синхронизации записи и колонки.

    SqlSyncAdapterBuilder использует эту информацию при создании адаптера синхронизации и команд на Transact-SQL для работы с SQL Server (версий 2000 и выше). Однако эффективность порождаемого им кода вызывает определенные сомнения – чтобы добиться хорошей производительности, придется все же вернуться к собственноручному созданию необходимых хранимых процедур.

    Следующий код создает объект SyncAdapter для двунаправленной синхронизации таблицы Customer.

    Прокси, сервис и транспорт

    Прокси, сервис и транспортный механизм используются в многоуровневой и сервис-ориентированной архитектурах. В многоуровневых приложениях используется Microsoft.Synchronization.Data.Server.dll, обычно располагающаяся в промежуточном слое. Прокси и сервис нужны, чтобы связать клиента с промежуточным слоем. Клиентский код приложения обращается к расположенному на клиенте прокси серверного провайдера синхронизации (ServerSyncProviderProxy), а не к самому провайдеру. Прокси связывается с сервисом, расположенным на промежуточном уровне, а сервис, в свою очередь, связывается с серверным провадером.

    В сервис-ориентированных приложениях Microsoft.Synchronization.Data.Server.dll не используется. Код приложения должен предоставлять функциональность, которую обычно предоставляют адаптеры и серверный провайдер синхронизации.

    Консольное приложение, использующее Sync Services для ADO.NET

    Теперь, когда принципы работы Sync Services вам известны, попробуем создать простое консольное приложение, которое скачивает с сервера некий набор данных, а затем обновляет его. Это, конечно, очень примитивное приложение, зато в нем собран воедино код, разбросанный по всей документации MSF.

    Чтобы приложение работало, нужно, чтобы на вашей машине были установлены Sync Services (приложение использует Microsoft.Synchronization.dll, Microsoft.Synchronization.Data.dll, Microsoft.Synchronization.Data.Server.dll и Microsoft.Synchronization.Data.SqlServerCe.dll), SQL Server Compact 3.5 SP1 и какой-нибудь еще SQL Server (например, SQL Server Express, поставляемый с Visual Studio), на котором будет лежать серверная БД. В строках подключения используется localhost. Если вы используете SQL Server Express, замените localhost на .\sqlexpress. В качестве БД используется база-пример, входящая в состав Sync Services, подробнее см. http://msdn2.microsoft.com/en-us/library/bb726041(SQL.100).aspx.

    Приложение состоит из шести классов:

    • SampleSyncAgent. Этот класс унаследован от SyncAgent и содержит SyncTable.
    • SampleServerSyncProvider. Этот класс унаследован от DbServerSyncProvider и содержит SyncAdapter.
    • SampleClientSyncProvider. Этот класс унаследован от SqlCeClientSyncProvider. в данном примере он содержит только строку подключения к клиентской БД.
    • SampleStats. Этот класс использует статистику, возвращаемую классом SyncAgent.
    • Program. Этот класс выполняет подготовку к синхронизации, используя методы класса Utility.
    • Utility. Это класс содержит всю функциональность, не связанную с синхронизацией – информацию о строках подключения.

    Прежде чем перейти непосредственно к коду, разберемся с основными действиями приложения.

    Создание SyncTable

    Следующий код создает объект SyncTable для таблицы Customer, указывает направление синхронизации и то, как таблица должна быть создана на клиенте. Если такая таблица уже есть, она будет пересоздана при первой синхронизации.

    Использование SqlSyncAdapterBuilder

    В данном случае адаптер синхронизации создается с помощью SqlSyncAdapterBuilder. Этот вопрос (и код) уже был разобран выше, поэтому здесь нет смысла останавливаться на этом.

    Команда New Anchor

    Следующий код служит для получения нового значения метки синхронизации с сервера. Это значение сохраняется в клиентской БД. При синхронизации значения, полученной при этой и при предыдущей синхронизации, служат верхней и нижней границами

    В данном случае MIN_ACTIVE_ROWVERSION возвращает значение времени с сервера (MIN_ACTIVE_ROWVERSION появилась в SQL Server 2005 Service Pack 2). Время используется потому, что в колонках, указанных при использовании SqlSyncAdapterBuilder, используются значения времени. Если бы там булла указана дата, можно было бы использовать, например, GETUTCDATE().

    Класс SyncSession содержит несколько строковых констант, которые можно использовать в командах синхронизации. Одна из них - SyncNewReceivedAnchor.