The following is my attachment trigger when I update attachment with same key multiple time then the concurrent error occur.
-----------------------------------------------------------------------------------------------------------------------------------------------------------
public class SendCommandForAttachmentPutTrigger : AbstractAttachmentPutTrigger
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
private bool IsNsbrReplication { get; set; }
private string NsbrSnapshorKeySuffix { get; set; }
public override VetoResult AllowPut(string key, Stream data, RavenJObject metadata)
{
IsNsbrReplication = ReplicationHelper.ContainNsbrReplicationFlag(metadata);
return base.AllowPut(key, data, metadata);
}
public override void OnPut(string key, Stream data, RavenJObject metadata)
{
if (ReplicationHelper.ContainNsbrReplicationFlag(metadata))
{
ReplicationHelper.RemoveNsbrReplicationFlag(metadata);
}
base.OnPut(key, data, metadata);
}
public override void AfterPut(string key, Stream data, RavenJObject metadata, Etag etag)
{
if (!IsNsbrReplication && !MessageDefinition.IsSystemAttachment(key))
{
if (TriggerHelper.UseRobustWayToCatchUnsentMessage(Database))
{
this.NsbrSnapshorKeySuffix = Guid.NewGuid().ToString();
StoreFailedSendingMessage(key, data, metadata, etag, this.NsbrSnapshorKeySuffix);
}
}
base.AfterPut(key, data, metadata, etag);
}
public override void AfterCommit(string key, Stream data, RavenJObject metadata, Etag etag)
{
//if data is bigger than 3.5M, then send it as databus
//else send it as normal message
if (IsNsbrReplication)
{
return;
}
if (MessageDefinition.IsSystemAttachment(key)) // we don't deal with system attachment
return;
try
{
var replicationSourceInfoJson = ReplicationHelper.CreateReplicationSourceJson(GlobalBus.HostName,
Database.Name, etag.ToString());
byte[] dataByte = ReplicationHelper.GetBytesFromStream(data);
if (MessageDefinition.IsLargeMessage(dataByte))
{
var bigMessage = new PutBigAttachment
{
Key = key, Etag = etag.ToString(),
AttachmentDataBus = dataByte,
MetadataJsonString = metadata.ToString(),
ReplicationSourceInfoJson = replicationSourceInfoJson
};
GlobalBus.Bus.Send(bigMessage);
}
else
{
var message = new PutAttachment { Key = key, Etag = etag.ToString(),
AttachmentData = dataByte,
MetadataJsonString = metadata.ToString(),
ReplicationSourceInfoJson = replicationSourceInfoJson
};
GlobalBus.Bus.Send(message);
}
if (TriggerHelper.UseRobustWayToCatchUnsentMessage(Database))
{
Database.Delete(RavenConstant.NsbrUnsentAttachmentSnapshotKeyPrefix + this.NsbrSnapshorKeySuffix,null,null);
Database.DeleteStatic(RavenConstant.NsbrUnsentAttachmentKeyPrifix + this.NsbrSnapshorKeySuffix, null);
}
}
catch (Exception e)
{
if (!TriggerHelper.UseRobustWayToCatchUnsentMessage(Database))
{
var snapshotKeySuffix=Guid.NewGuid().ToString();
try
{
StoreFailedSendingMessage(key, data, metadata, etag, snapshotKeySuffix);
}
catch (Exception ex)
{
logger.Fatal("Store PutAttachment Error:({0}-snapshotkeysuffix={1}) {2}", key, snapshotKeySuffix, ex);
}
}
logger.FatalException("SendCommandForAttachmentPutTrigger key="+key, e);
}
}
private void StoreFailedSendingMessage(string key, Stream data, RavenJObject metadata, Etag etag,string snapshotkeysuffix)
{
var snapShotAttachmentKey = RavenConstant.NsbrUnsentAttachmentKeyPrifix+snapshotkeysuffix;
var ravenJObject =
RavenJObject.FromObject(new NsbrUnsentAttachmentSnapshot
{
Key = key,
Etag = etag.ToString(),
AttachmentKey = snapShotAttachmentKey,
Metadata = metadata.ToString(),
ActionType = RavenConstant.NsbrUnsentMessageActionTypePut,
SourceDb = Database.Name,
SourceHost = GlobalBus.HostName
}
);
var snapShotDocMetadata = new RavenJObject{
{Constants.RavenEntityName,RavenJToken.FromObject(RavenConstant.NsbrUnsentAttachmentSnapshotKeyPrefix.TrimEnd('/'))}
};
Database.Put(RavenConstant.NsbrUnsentAttachmentSnapshotKeyPrefix + snapshotkeysuffix,
null,ravenJObject,
snapShotDocMetadata, null);
var snapShotAttachmentMetadata = new RavenJObject { {"SourceSnapshotEtag",etag.ToString()},
{"SourceSnapShotKey",key}
};
data.Position = 0;
Database.PutStatic(snapShotAttachmentKey, null, data, snapShotAttachmentMetadata);
}
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在 Nsbr.RavenRestClients.RestClientExtensions.ExtensionExecute(RestClient client, IRestRequest request, Boolean useLock) 位置 d:\LTSS\FEIInternal\eLtss\Tools\RavenReplication\Code\Nsbr.RavenRestClients\RestClientExtensions.cs:行号 56
在 Nsbr.RavenRestClients.RavenHttpApiProxy.PutAttachment(String key, Byte[] bytes, IDictionary`2 metada, String baseUrl, Boolean useLock) 位置 d:\LTSS\FEIInternal\eLtss\Tools\RavenReplication\Code\Nsbr.RavenRestClients\RavenHttpApiProxy.cs:行号 126