Регулярно мой клиент сталкивается со следующим исключение:
Telerik.OpenAccess.OpenAccessException: Change operation canceled by user.
at OpenAccessRuntime.ExceptionWrapper.Throw()
at OpenAccessRuntime.DataObjects.PCStateMan.handleException(Exception x)
at OpenAccessRuntime.DataObjects.PCStateMan.SetField[T](PersistenceCapable _pc, Int32 field, T currentValue, T newValue)
at App1.Server.Core.Domain.CommandOrderPart.OpenAccessEnhancedSet_status(CommandOrderPart owner, OrderStatus value)
at App1.Server.Core.Domain.CommandOrderPart.set_Status(OrderStatus value)
at App2.Helpers.ExtensionMethods.SetStatus(CommandOrderPart orderPart, String status) in C:\Source1.cs:line 47
at App2.Manager.RequestOrderStatus(JbtOrder order) in C:\Source2.cs:line 668
Telerik.OpenAccess.OpenAccessException: Change operation canceled by user.
at OpenAccessRuntime.ExceptionWrapper.Throw()
at OpenAccessRuntime.DataObjects.PCStateMan.handleException(Exception x)
at OpenAccessRuntime.DataObjects.PCStateMan.SetField[T](PersistenceCapable _pc, Int32 field, T currentValue, T newValue)
at App1.Server.Core.Domain.CommandOrderPart.OpenAccessEnhancedSet_status(CommandOrderPart owner, OrderStatus value)
at App1.Server.Core.Domain.CommandOrderPart.set_Status(OrderStatus value)
at App2.Helpers.ExtensionMethods.SetStatus(CommandOrderPart orderPart, String status) in C:\Source1.cs:line 47
at App2.Manager.RequestOrderStatus(JbtOrder order) in C:\Source2.cs:line 668
Что именно означает «Операция изменения отменена пользователем»? Хорошо, я понимаю, что мои приложения хотят установить статус (который является «операцией изменения»), но кто является пользователем, создающим это исключение? Могу ли я получить дополнительную информацию из базы данных? Какая таблица, представление или диагностика? ...?
декомпиляция Telerik OpenAccess DLL**
После декомпиляции Telerik OpenAccess DLL я обнаружил два случая отмены операции изменения пользователем< /code>:
- Файл «DisconnectedStateManager.cs»:
object pc,
int field,
object oldV,
object newV)
{
ChangeEventArgs ev = new ChangeEventArgs(pc, this.cmd.getFieldName(field), oldV, newV, this.state == (short) 4, true);
this.repository.tracker.FireChanging(ev);
return !ev.Cancel ? ev : throw new OpenAccessException("Change operation canceled by user.", true);
}
- Файл ".../SPI/TrackingImpl.cs":
/// Not intended for application use.
///
The event to raise.
public void FireChanging(ChangeEventArgs ev)
{
if (this.evChanging == null)
return;
this.evChanging(this.owner, ev);
if (ev.Cancel)
throw new OpenAccessException("Change operation canceled by user.", true);
}
PcStateMan.cs:
В «PcStateMan.cs» в handleException(...) можно увидеть следующее:
private void handleException(Exception x)
{
if (BindingSupportImpl.Instance.isOwnException(x))
throw new ExceptionWrapper(x).Throw();
throw BindingSupportImpl.Instance.internally(x.Message, x).Throw();
}
Это означает, что условие BindingSupportImpl.Instance.isOwnException(x) истинно (что бы это ни значило).
Изменить: тайм-аут тайм-аута БД приложения:
Если настроен тайм-аут для App1 и/или App2, это может произойти (просто представьте, что App1.....CommandOrderPart.Set() занимает слишком много времени, в то время как App2 имеет настройку тайм-аута базы данных, это уже может вызвать проблему). Где я могу найти эти настройки таймаута?
Редактировать: предложение найти SQL-оператор, вызывающий такую ситуацию
По-видимому, проблема возникает при изменении статуса App1.....CommandOrderPart. Можно создать SQL-трассировку, отслеживающую все транзакции, выполняемые с этим объектом, следующим образом:
DECLARE @TraceID INT;
DECLARE @MaxFileSize BIGINT = 50; -- File size limit in MB
DECLARE @TraceFilePath NVARCHAR(256) = N'C:\SQLTraces\Trace_OrderPart'; -- Base trace file path
-- Step 1: Create a new trace
EXEC sp_trace_create
@traceid = @TraceID OUTPUT,
@options = 2, -- File rollover enabled
@tracefile = @TraceFilePath,
@maxfilesize = @MaxFileSize,
@stoptime = NULL; -- No automatic stop
-- Step 2: Set events to capture
-- Add events to monitor SQL statements and related information
EXEC sp_trace_setevent @TraceID, 40, 1, 1; -- EventClass (SP:StmtStarting) TextData
EXEC sp_trace_setevent @TraceID, 40, 4, 1; -- EventClass (SP:StmtStarting) TransactionId
EXEC sp_trace_setevent @TraceID, 40, 9, 1; -- EventClass (SP:StmtStarting) ClientProcessID
EXEC sp_trace_setevent @TraceID, 40, 10, 1; -- EventClass (SP:StmtStarting) ApplicationName
EXEC sp_trace_setevent @TraceID, 40, 11, 1; -- EventClass (SP:StmtStarting) LoginName
EXEC sp_trace_setevent @TraceID, 40, 12, 1; -- EventClass (SP:StmtStarting) SPID
EXEC sp_trace_setevent @TraceID, 40, 13, 1; -- EventClass (SP:StmtStarting) ClientProcessID
EXEC sp_trace_setevent @TraceID, 40, 14, 1; -- EventClass (SP:StmtStarting) StartTime
EXEC sp_trace_setevent @TraceID, 40, 15, 1; -- EventClass (SP:StmtStarting) EndTime
EXEC sp_trace_setevent @TraceID, 40, 20, 1; -- EventClass (SP:StmtStarting) Severity
EXEC sp_trace_setevent @TraceID, 40, 23, 1; -- EventClass (SP:StmtStarting) Success
EXEC sp_trace_setevent @TraceID, 40, 25, 1; -- EventClass (SP:StmtStarting) IntegerData
EXEC sp_trace_setevent @TraceID, 40, 27, 1; -- EventClass (SP:StmtStarting) EventClass
EXEC sp_trace_setevent @TraceID, 40, 31, 1; -- EventClass (SP:StmtStarting) Error Number
EXEC sp_trace_setevent @TraceID, 40, 34, 1; -- EventClass (SP:StmtStarting) ObjectName
EXEC sp_trace_setevent @TraceID, 40, 49, 1; -- EventClass (SP:StmtStarting) RequestID
EXEC sp_trace_setevent @TraceID, 40, 55, 1; -- EventClass (SP:StmtStarting) IntegerData2
EXEC sp_trace_setevent @TraceID, 41, 1, 1; -- EventClass (SP:StmtCompleted) TextData
EXEC sp_trace_setevent @TraceID, 41, 4, 1; -- EventClass (SP:StmtCompleted) TransactionId
EXEC sp_trace_setevent @TraceID, 41, 9, 1; -- EventClass (SP:StmtCompleted) ClientProcessID
EXEC sp_trace_setevent @TraceID, 41, 10, 1; -- EventClass (SP:StmtCompleted) ApplicationName
EXEC sp_trace_setevent @TraceID, 41, 11, 1; -- EventClass (SP:StmtCompleted) LoginName
EXEC sp_trace_setevent @TraceID, 41, 12, 1; -- EventClass (SP:StmtCompleted) SPID
EXEC sp_trace_setevent @TraceID, 41, 13, 1; -- EventClass (SP:StmtCompleted) ClientProcessID
EXEC sp_trace_setevent @TraceID, 41, 14, 1; -- EventClass (SP:StmtCompleted) StartTime
EXEC sp_trace_setevent @TraceID, 41, 15, 1; -- EventClass (SP:StmtCompleted) EndTime
EXEC sp_trace_setevent @TraceID, 41, 20, 1; -- EventClass (SP:StmtCompleted) Severity
EXEC sp_trace_setevent @TraceID, 41, 23, 1; -- EventClass (SP:StmtCompleted) Success
EXEC sp_trace_setevent @TraceID, 41, 25, 1; -- EventClass (SP:StmtCompleted) IntegerData
EXEC sp_trace_setevent @TraceID, 41, 27, 1; -- EventClass (SP:StmtCompleted) EventClass
EXEC sp_trace_setevent @TraceID, 41, 31, 1; -- EventClass (SP:StmtCompleted) Error Number
EXEC sp_trace_setevent @TraceID, 41, 34, 1; -- EventClass (SP:StmtCompleted) ObjectName
EXEC sp_trace_setevent @TraceID, 41, 49, 1; -- EventClass (SP:StmtCompleted) RequestID
EXEC sp_trace_setevent @TraceID, 41, 55, 1; -- EventClass (SP:StmtCompleted) IntegerData2
-- Step 3: Set a filter for the table CommandOrderParts
EXEC sp_trace_setfilter @TraceID, 55, 0, 6, N'dbo.CommandOrderParts'; -- ObjectName filter
-- Optional: Add a filter for ApplicationName to capture specific applications
EXEC sp_trace_setfilter @TraceID, 10, 0, 6, N'File_App1'; -- Filter for File_App1.dll
EXEC sp_trace_setfilter @TraceID, 10, 1, 6, N'File_App2'; -- Filter for File_App2.dll
-- Step 4: Start the trace
EXEC sp_trace_setstatus @TraceID, 1; -- Start the trace
-- Step 5: Stop the trace
EXEC sp_trace_setstatus @TraceID, 0; -- Stop the trace
Очевидно, я начинаю выполнение этого SQL-скрипта до шага 4. Если я хочу, чтобы сценарий остановился, я запускаю шаг 5.
Ну, раньше Я забыл: сценарий, который я впервые нашел, содержал другие значения для событий. Я выполнил SQL-запрос SELECT @@VERSION и в результате получился Microsoft SQL Server 2017 (RTM-CU31-GDR) (KB5029376)..., я решил зайти на эту страницу, чтобы получить определения событий:

Изменить чувствительность к взаимоблокировкам
К вашему сведению: приложение, похоже, чувствительно к взаимоблокировкам: менее чем за шесть месяцев я обнаружил 213 исключений, связанных с взаимоблокировками, подобных этому:
2024-10-28 12:53:31.5199 | Error | App1.RaiseConnectionFailed | Telerik.OpenAccess.RT.sql.SQLException: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. ---> System.Data.SqlClient.SqlException: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
at System.Data.SqlClient.SqlDataReader.Read()
at OpenAccessRuntime.Intellitrace.Read(DbDataReader reader, String id)
at Telerik.OpenAccess.Runtime.Logging.LoggingDbDataReader.Read()
at Telerik.OpenAccess.RT.Adonet2Generic.Impl.ResultSetImp.next()
--- End of inner exception stack trace ---
at Telerik.OpenAccess.RT.Adonet2Generic.Impl.ResultSetImp.next()
at OpenAccessRuntime.Relational.fetch.FetchResultImp.rsNext()
at OpenAccessRuntime.Relational.fetch.FetchResultImp.hasNext()
Подробнее здесь: https://stackoverflow.com/questions/792 ... an-by-that