Batch updates

object edited this page Oct 15, 2012 · 5 revisions

To optimize network communication OData protocol supports sending multiple updates in batches. This is not the same as wrapping updates in transactions (the underlying OData service provider may not even support transactions, and OData client would be completely unaware of this fact), however Simple.Data transactional features provide the closest match to batch updates. So if you use Simple.Data OData adaptenr and want to pack OData updates in single HTTP request, use Simple.Data transactions but be aware that this operation has no direct relationship to database transactions and their ACID principles.

Use Commit to send a generated OData batch to the server, otherwise use Rollback to cancel the current batch.


Insert a single entry in a batch and commit

using (var tx = _db.BeginTransaction())
{
    tx.Products.Insert(ProductName: "Test1", UnitPrice: 21m);
    tx.Commit();
}
var product = _db.Products.FindByProductName("Test1");
Assert.True(product.ProductID > 0);

Request URI: POST /$batch
Request content:

--batch_6799b226-8c57-4bd6-b8b0-700f83cd0b71
Content-Type: multipart/mixed; boundary=changeset_2a9a9ccb-5d0c-4f77-bd95-82bf6c0c0848

--changeset_2a9a9ccb-5d0c-4f77-bd95-82bf6c0c0848
Content-Type: application/http
Content-Transfer-Encoding:binary

POST http://nrkdt58341/Temporary_Listen_Addresses/SimpleODataTestService2/Products HTTP/1.1
Content-ID: 1
Content-Type: application/atom+xml;type=entry
Content-Length: 496

<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title />
  <updated>2012-10-15T14:57:35.5030000Z</updated>
  <author>
    <name />
  </author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:ProductName>Test1</d:ProductName>
      <d:UnitPrice m:type="Edm.Decimal">21</d:UnitPrice>
    </m:properties>
  </content>
</entry>
--changeset_2a9a9ccb-5d0c-4f77-bd95-82bf6c0c0848--
--batch_6799b226-8c57-4bd6-b8b0-700f83cd0b71--

Insert a single entry in a batch and rollback

using (var tx = _db.BeginTransaction())
{
    tx.Products.Insert(ProductName: "Test2", UnitPrice: 21m);
    tx.Rollback();
}
var product = _db.Products.FindByProductName("Test2");
Assert.Null(product);

No HTTP request is sent


Insert multiple entries in a batch

using (var tx = _db.BeginTransaction())
{
    tx.Products.Insert(ProductName: "Test3", UnitPrice: 21m);
    tx.Products.Insert(ProductName: "Test4", UnitPrice: 22m);
    tx.Commit();
}
var product = _db.Products.FindByProductName("Test3");
Assert.Equal(21m, product.UnitPrice);
product = _db.Products.FindByProductName("Test4");
Assert.Equal(22m, product.UnitPrice);

Request URI: POST /$batch
Request content:

--batch_77b3aa21-b11a-4307-b0df-36a5c566667e
Content-Type: multipart/mixed; boundary=changeset_f4b2eee4-7345-4344-b592-be7b7348e53a

--changeset_f4b2eee4-7345-4344-b592-be7b7348e53a
Content-Type: application/http
Content-Transfer-Encoding:binary

POST http://nrkdt58341/Temporary_Listen_Addresses/SimpleODataTestService2/Products HTTP/1.1
Content-ID: 1
Content-Type: application/atom+xml;type=entry
Content-Length: 496

<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title />
  <updated>2012-10-15T15:03:45.3000000Z</updated>
  <author>
    <name />
  </author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:ProductName>Test3</d:ProductName>
      <d:UnitPrice m:type="Edm.Decimal">21</d:UnitPrice>
    </m:properties>
  </content>
</entry>
--changeset_f4b2eee4-7345-4344-b592-be7b7348e53a
Content-Type: application/http
Content-Transfer-Encoding:binary

POST http://nrkdt58341/Temporary_Listen_Addresses/SimpleODataTestService2/Products HTTP/1.1
Content-ID: 2
Content-Type: application/atom+xml;type=entry
Content-Length: 496

<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title />
  <updated>2012-10-15T15:03:45.3660000Z</updated>
  <author>
    <name />
  </author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:ProductName>Test4</d:ProductName>
      <d:UnitPrice m:type="Edm.Decimal">22</d:UnitPrice>
    </m:properties>
  </content>
</entry>
--changeset_f4b2eee4-7345-4344-b592-be7b7348e53a--
--batch_77b3aa21-b11a-4307-b0df-36a5c566667e--

Insert multiple entries and create a link between them in single a batch

dynamic category;
using (var tx = _db.BeginTransaction())
{
    category = tx.Categories.Insert(CategoryName: "Test15");
    tx.Products.Insert(ProductName: "Test16", UnitPrice: 18m, Category: category);
    tx.Commit();
}
category = _db.Categories.FindByCategoryName("Test15");
var product = _db.Products.WithCategory().FindByProductName("Test16");
Assert.Equal(category.CategoryName, product.Category.CategoryName);

Request URI: POST /$batch
Request content:

--batch_6c440ee2-34a4-41a6-b891-331a5b54ee29
Content-Type: multipart/mixed; boundary=changeset_98134adc-dba3-419d-b44f-256fd4849c25

--changeset_98134adc-dba3-419d-b44f-256fd4849c25
Content-Type: application/http
Content-Transfer-Encoding:binary

POST http://nrkdt58341/Temporary_Listen_Addresses/SimpleODataTestService2/Categories HTTP/1.1
Content-ID: 1
Content-Type: application/atom+xml;type=entry
Content-Length: 441

<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title />
  <updated>2012-10-15T15:09:14.9040000Z</updated>
  <author>
    <name />
  </author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:CategoryName>Test15</d:CategoryName>
    </m:properties>
  </content>
</entry>
--changeset_98134adc-dba3-419d-b44f-256fd4849c25
Content-Type: application/http
Content-Transfer-Encoding:binary

POST http://nrkdt58341/Temporary_Listen_Addresses/SimpleODataTestService2/Products HTTP/1.1
Content-ID: 2
Content-Type: application/atom+xml;type=entry
Content-Length: 497

<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title />
  <updated>2012-10-15T15:09:15.0160000Z</updated>
  <author>
    <name />
  </author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:ProductName>Test16</d:ProductName>
      <d:UnitPrice m:type="Edm.Decimal">18</d:UnitPrice>
    </m:properties>
  </content>
</entry>
--changeset_98134adc-dba3-419d-b44f-256fd4849c25
Content-Type: application/http
Content-Transfer-Encoding:binary

PUT $2/$links/Category HTTP/1.1
Content-ID: 3
Content-Type: application/xml
Content-Length: 84

<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">$1</uri>
--changeset_98134adc-dba3-419d-b44f-256fd4849c25--
--batch_6c440ee2-34a4-41a6-b891-331a5b54ee29--

See also:
Modifying data
OData batch processing