I update multiple items in a loop and then call executeQueryAsync()
on ClientContext
class and this call returns error (failed callback is invoked). Can I be sure that not a single item was updated of all these I wanted to update? Is there a chance that some of them will get updated and some of them will not? In other words, is this operation transactional? I cannot find a single post about it. I'm asking about CSOM model not server solutions.
-
AFAIK, not even the "batch operation" api is actually transactional, so I would guess it is a "no", but I will leave this one open until I can actually check.– SPArcheon - on strikeCommented Jan 4, 2016 at 19:24
-
1Good question, I would say everything in SharePoint is Item based And there is no Rollback mechanism I know of. So if you update multiple items and one fails... then one fails. You could test by adding item validation and make it fail on one item,– Danny '365CSI' EngelmanCommented Jan 4, 2016 at 20:09
2 Answers
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://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.