# Transaction Deadline Policies

> A transaction deadline policy defines the temporal conditions under which the database kernel should interrupt a running transaction and return control to the application. eXtremeDB/rt supports customizable transaction deadline policies. Two policies are pre-configured in the kernel: the strict deadline policy and the adaptable rollback policy.

> In addition, applications can implement their own custom deadline policies that reflect their specific criteria for interrupting transactions. These custom policies can be registered with the database kernel at runtime.

> ### Commit Behaviour

> One key difference from the mainstream version of eXtremeDB is the behaviour of mco_trans_commit(). In the mainstream version, if an error is encountered during commit, the transaction is automatically rolled back. However, this rollback could potentially cause the application to exceed its deadline.

> In eXtremeDB/rt, if an error occurs during the commit process, the error is returned to the application without performing an automatic rollback. The application is then responsible for explicit initiation of the rollback (using mco_trans_rollback() or mco_trans_end()).

> ## Strict deadline policy

> The Strict deadline policy favors temporal consistency over logical consistency by enforcing hard limits on transaction duration.

> Unlike the Adaptable policy, the database kernel does not reserve time for rollback. A transaction is allowed to run until its defined deadline, as specified in the mco_trans_start() parameters. Once the deadline is reached, any database API call immediately returns `MCO_E_INTERRUPTED`. At this point, the database is left in a logically inconsistent state, and a rollback must be initiated.

> The application must schedule the rollback by setting a new deadline using mco_trans_set_params(), then invoke mco_trans_rollback() to restore consistency. While unlikely, `mco_trans_rollback()` may itself return `MCO_E_INTERRUPTED` and must be rescheduled and retried until it completes successfully and returns `MCO_S_OK`.

> Note: If mco_trans_end() is used instead of an explicit mco_trans_commit() / mco_trans_rollback() pair, real-time guarantees cannot be upheld. Internally, `mco_trans_end()` attempts to commit first, and if it fails with `MCO_E_INTERRUPTED`, it immediately proceeds to rollback — despite the deadline having expired.

> Please refer to the sample rt_policy_strict for detailed implementation.

> ## Adaptable Deadline Policy

> The adaptable deadline policy prioritizes logical database consistency over temporal consistency. A deadline value is passed to mco_trans_start(), and the database kernel monitors the transaction’s progress against this deadline. At designated cancellation points, it estimates the time required to roll back the current transaction. If the kernel determines that continuing would risk exceeding the deadline, it returns `MCO_E_INTERRUPTED`, prompting the application to immediately call mco_trans_rollback(). As long as the rollback begins without delay, it is guaranteed to complete before the original deadline and return `MCO_S_OK`, assuming no other errors occur.

> If the rollback is delayed in the application, it may fail to complete within the deadline and return `MCO_E_INTERRUPTED`. When this happens, the database is left in a logically inconsistent state, and the rollback must be rescheduled and executed. Since the original deadline has expired, a new one must be set using mco_trans_set_params() if the application is to remain within real-time constraints.

> mco_trans_commit() may also return `MCO_E_INTERRUPTED` if the commit cannot complete before the deadline—this can happen, for example, if the application delays calling commit after completing the transaction workload. In such cases, a rollback must likewise be scheduled and executed. As an alternative, applications can use mco_trans_end() instead of calling mco_trans_commit() directly. This instructs the database kernel to automatically perform a rollback if the internal commit attempt fails. mco_trans_end() is guaranteed to return within the allotted time.

> Please refer to the sample rt_policy_adaptable for detailed implementation.

> ## Custom Deadline Policies

> Applications can supply their own callback to the kernel via mco_trans_rt_register_callback(). It will be invoked by the eXtremeDB/rt kernel at the cancellation points to check if it can continue the current transaction or should interrupt its execution, returning MCO_E_INTERRUPTED.

> ## Time Measurements

> The kernel uses "human" time units—milliseconds—for time measurement. For example, its synchronization primitives, which are based on semaphores, define semaphore timeouts in milliseconds. Applications also use milliseconds to specify transaction deadlines, and functions such as mco_trans_rt_remaining_time() and mco_trans_rt_estimate_rollback() return time intervals in milliseconds.

> Internally, the kernel’s mco_system_get_current_time() function returns the current system time in microseconds, measured from a predefined point in time (which may be the Unix epoch, but not necessarily). For convenience, the macro MCO_SYSTEM_GET_CURRENT_TIME_MSEC() converts this value to milliseconds. If needed, applications can override the kernel’s default time-reading function by using the set_system_get_current_time_function() API:

>         typedef timer_unit (*mco_system_get_current_time_fptr_t)(void);
>         mco_system_get_current_time_fptr_t 		set_system_get_current_time_function(mco_system_get_current_time_fptr_t fptr);

> The set_system_get_current_time_function() API allows the application to provide a pointer to a custom function, which the database kernel will use in place of its default implementation when mco_system_get_current_time() is called. The custom function pointer is valid only within the context of the process that sets it. Other processes will continue to use the default implementation unless they explicitly override it as well.