Wp_query: sort by PHP variable

To the best of my knowledge, you cannot sort a query by two different parameters without an additional iteration over the retrieved posts.

Since that ideally should be avoided, let me suggest a different approach:

How about incorporating an additional meta value “sort_date”, or the like? And then, in your saving routine, save either the end date of the exhibition or the publish date as “sort_date”.

Saving:

function save_sort_meta( $post_id ) {
    $prev_val = get_post_meta( $post_id, 'sort_date', true );
    /* set value only if not set yet (i.e. if this is a new post and not an update ) */
    if ( empty($prev_val) ) {
        if ( 'exhibitions' === $_POST['post_type'] ) {
            update_post_meta( $post_id, 'sort_date', $_POST['end_date'] );
        } else {
            /* using time() assuming "end_date" is a unix timestamp, adjust if not */
            update_post_meta( $post_id, 'sort_date', time() );
        }
    }
}
add_action( 'save_post', 'save_sort_meta' );

The Query:

$args = array(
    'post_status' => 'publish',
    'post_type' = array( 'exhibitions', 'posts' ),
    'meta_key' => 'sort_date',
    'order' => 'DESC',
    'orderby' => 'meta_value_num'
);
$exhibitions_and_posts = new WP_Query( $args );

As an aside, I’d recommend giving the post type a singular name.