public async Task <bool> SaveAsync(IEventBase <K> evt, byte[] bytes, string uniqueId = null) { var table = await tableInfo.GetTable(evt.Timestamp); if (!saveSqlDict.TryGetValue(table.Name, out var saveSql)) { saveSql = $"INSERT INTO {table.Name}(stateid,uniqueId,typecode,data,version) VALUES(@StateId,@UniqueId,@TypeCode,@Data,@Version)"; saveSqlDict.TryAdd(table.Name, saveSql); } if (string.IsNullOrEmpty(uniqueId)) { uniqueId = evt.GetUniqueId(); } try { using (var conn = tableInfo.CreateConnection()) { await conn.ExecuteAsync(saveSql, new { StateId = evt.StateId.ToString(), UniqueId = uniqueId, evt.TypeCode, Data = bytes, evt.Version }); } return(true); } catch (Exception ex) { if (!(ex is PostgresException e && e.SqlState == "23505")) { throw ex; } } return(false); }
public async Task <bool> SaveAsync(IEventBase <K> data, byte[] bytes, string uniqueId = null) { var table = await tableInfo.GetTable(data.Timestamp); var saveSql = $"INSERT INTO {table.Name}(Id,stateid,msgid,typecode,data,version) VALUES(@Id,@StateId,@MsgId,@TypeCode,@Data,@Version)"; data.Id = OGuid.GenerateNewId().ToString(); string msgId = uniqueId; if (string.IsNullOrEmpty(msgId)) { msgId = data.Id; } try { using (var conn = tableInfo.CreateConnection()) { await conn.ExecuteAsync(saveSql, new { data.Id, StateId = data.StateId.ToString(), MsgId = msgId, data.TypeCode, Data = bytes, data.Version }); } return(true); } catch (Exception ex) { if (!(ex is Npgsql.PostgresException e && e.SqlState == "23505")) { throw ex; } } return(false); }
private async ValueTask FlowProcess() { var start = DateTime.UtcNow; var wrapList = new List <EventBytesTransactionWrap <K> >(); var copySql = copySaveSqlDict.GetOrAdd((await tableInfo.GetTable(DateTime.UtcNow)).Name, key => $"copy {key}(stateid,uniqueId,typecode,data,version) FROM STDIN (FORMAT BINARY)"); try { using (var conn = tableInfo.CreateConnection() as NpgsqlConnection) { await conn.OpenAsync(); using (var writer = conn.BeginBinaryImport(copySql)) { while (EventSaveFlowChannel.TryReceive(out var evt)) { wrapList.Add(evt); writer.StartRow(); writer.Write(evt.Value.StateId.ToString(), NpgsqlDbType.Varchar); writer.Write(evt.UniqueId, NpgsqlDbType.Varchar); writer.Write(evt.Value.TypeCode, NpgsqlDbType.Varchar); writer.Write(evt.Bytes, NpgsqlDbType.Bytea); writer.Write(evt.Value.Version, NpgsqlDbType.Bigint); if ((DateTime.UtcNow - start).TotalMilliseconds > 100) { break; //保证批量延时不超过100ms } } writer.Complete(); } } wrapList.ForEach(wrap => wrap.TaskSource.TrySetResult(true)); } catch { var saveSql = await GetInsertSql(); using (var conn = tableInfo.CreateConnection()) { await conn.OpenAsync(); using (var trans = conn.BeginTransaction()) { try { foreach (var w in wrapList) { w.Result = await conn.ExecuteAsync(saveSql, new { StateId = w.Value.StateId.ToString(), w.UniqueId, w.Value.TypeCode, Data = w.Bytes, w.Value.Version }, trans) > 0; } trans.Commit(); wrapList.ForEach(wrap => wrap.TaskSource.TrySetResult(wrap.Result)); } catch (Exception e) { trans.Rollback(); wrapList.ForEach(wrap => wrap.TaskSource.TrySetException(e)); } } } } }