How to debug TransactionOutOfOrderException: in DatabaseConnection->rollback() in database.inc?
Basically the TransactionOutOfOrderException exception is triggered by transaction being rolled-back (see: rollback()) called by Commerce module which was triggered by inability to save your entity (such as validation errors like saving empty values for required fields). Check commerce_line_item.controller.inc or commerce_order.controller.inc files for more details when exactly rollback is triggered.

Since you're using entity metadata wrappers, it is strongly recommended that you should implement try...catch section to catch exceptions and add debugging errors into watchdog. Here is the sample syntax of saving node wrapper:

try {
  $node_wrapper = entity_metadata_wrapper('node', $node);
  $price = $node_wrapper-&gt;field_product-&gt;field_price-&gt;value();
} 
catch (EntityMetadataWrapperException $exc) {
  watchdog(
    'MODULE_NAME',
    'EntityMetadataWrapper exception in %function() &lt;pre&gt;@trace&lt;/pre&gt;',
    array('%function' =&gt; __FUNCTION__, '@trace' =&gt; $exc-&gt;getTraceAsString()),
    WATCHDOG_ERROR
  );
}


So adequately your code should look like:

if (empty($form_state['values']['product'])) {
  drupal_set_message(t('Missing product on the submit form! Form values: @values',
    array('@values' =&gt; print_r($form_state['values'], TRUE)), 'error');
  return;
}
// @todo: Do above condition for other parameters as well.
$selected_month = $form_state['values']['month'];
$selected_year = $form_state['values']['year'];
$order = commerce_order_new($form_state['values']['user'], 'checkout_checkout');
commerce_order_save($order);

try {
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
  $product = commerce_product_load($form_state['values']['product']);
  $line_item = commerce_product_line_item_new($product, 1, $order-&gt;order_id);
  commerce_line_item_save($line_item);
}
catch (Exception $e) {
  drupal_set_message(t('Error saving line item: @item, message: @error.',
    array('@item' =&gt; print_r($line_item, TRUE), '@error' =&gt; $e-&gt;getMessage())), 'error');
  watchdog_exception('mymodule', $e);
}

try {
  $order_wrapper-&gt;commerce_line_items[] = $line_item;
  $order_wrapper-&gt;save();
catch (Exception $e) {
  drupal_set_message(t('Error saving order: @order, message: @error.',
    array('@order' =&gt; print_r($order_wrapper, TRUE), '@error' =&gt; $e-&gt;getMessage())), 'error');
  watchdog_exception('mymodule', $e);
}


Note: Test the above code first on your testing environment.

So basically by implementing more logging into your code, you can see further what's missing and why it's failing.

For further debugging, ideally you should setup your local environment with copy of the database and reproduce the problem on your development machine.

Since you're dealing with submit handler, for easier debugging, you can use DevTools (in the supported browser) where you can repeat XHR requests, so you can see results after code changes without filling out the complex forms. If your form will require different token on each submit, ideally you should add die()/exit(); to prevent the form being completely submitted, this way you can test your form using quick and repeatable method.

For more sophisticated debugging, you should use step-by-step debugger by using some IDE editors which can support that, by enabling XDebug PHP extension. Or generate the trace file which can help you to find out more about your issue.