Sharepoint - Is context.executeQueryAsync a transactional operation?

I see you posted this in stackoverflow as well and not sure about the rules for providing answers, so hopefully the mods will not mind if I post my answer here as well:

SharePoint handles its internal updates in a transactional method, so updating a document will actually be multiple calls to the DB that if one method fails, will roll back the other changes so nothing is half updated on a failure.

However, that is not made available to us as an external developer. If you create an update that updates 9 items within your executeQueryAsync call and it fails on #7, then the first 6 will not be rolled back. You are going to have to write code to handle the failures and if rolling back is important, then you will have to manually roll back the changes within your code.

I have never seen this officially recorded in TechNet or anything like that, but have found supporting references from other veteran SharePoint developers:

https://social.msdn.microsoft.com/Forums/en-US/30004a3b-11bf-4fce-ba00-6946e8567be0/client-object-model-transactional-update-of-list-and-content-types?

https://stackoverflow.com/questions/4658111/transactional-integrity-sharepoint-list


I had the same question and used this PowerShell script to find out. The result is negative - we don't get transactional behaviour on list items.

Sending a valid list1ItemId and invalid list2ItemId results in the first item being updated despite an error on the second item.

param(
        [Parameter(Mandatory = $true)][string]$url,
        [Parameter(Mandatory = $true)][string]$list1Title,
        [Parameter(Mandatory = $true)][int]$list1ItemId,
        [Parameter(Mandatory = $true)][string]$list2Title,
        [Parameter(Mandatory = $true)][int]$list2ItemId,
        [Parameter(Mandatory = $true)][string]$text,
        [Parameter(Mandatory = $false)][switch]$promptForCredentials
)

$assemblyVersion = "15.0.0.0"
$clientDll = [System.Reflection.Assembly]::Load($("Microsoft.SharePoint.Client, Version={0}, Culture=neutral, PublicKeyToken=71e9bce111e9429c" -f $assemblyVersion))

$cred = $null
if ($promptForCredentials.IsPresent)
{
    $cred = Get-Credential
}

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$ctx.Credentials = $cred

$list1 = $ctx.Web.Lists.GetByTitle($list1Title)
$list1Item = $list1.GetItemById($list1ItemId)
$list1Item["Title"] = $text
$list1Item.Update()

$list2 = $ctx.Web.Lists.GetByTitle($list2Title)
$list2Item = $list2.GetItemById($list2ItemId)
$list2Item["Title"] = $text
$list2Item.Update()

$ctx.ExecuteQuery()

Termstore operations via CSOM do, however, support transactions. See CommitAll.