diff --git a/cps/editbooks.py b/cps/editbooks.py
index b5791c5419260ee83c9ed9624db0c9bbc416187f..dd8bf42067ec19ab017a46d792993aa772e70e59 100644
--- a/cps/editbooks.py
+++ b/cps/editbooks.py
@@ -1148,11 +1148,15 @@ def edit_list_book(param):
                                    'newValue':  ' & '.join([author.replace('|',',') for author in input_authors])}),
                        mimetype='application/json')
     book.last_modified = datetime.utcnow()
-    calibre_db.session.commit()
-    # revert change for sort if automatic fields link is deactivated
-    if param == 'title' and vals.get('checkT') == "false":
-        book.sort = sort
+    try:
         calibre_db.session.commit()
+        # revert change for sort if automatic fields link is deactivated
+        if param == 'title' and vals.get('checkT') == "false":
+            book.sort = sort
+            calibre_db.session.commit()
+    except (OperationalError, IntegrityError) as e:
+        calibre_db.session.rollback()
+        log.error("Database error: %s", e)
     return ret
 
 
@@ -1224,3 +1228,43 @@ def merge_list_book():
                     delete_book(from_book.id,"", True)
                     return json.dumps({'success': True})
     return ""
+
+@editbook.route("/ajax/xchange", methods=['POST'])
+@login_required
+@edit_required
+def table_xchange_author_title():
+    vals = request.get_json().get('xchange')
+    if vals:
+        for val in vals:
+            modif_date = False
+            book = calibre_db.get_book(val)
+            authors = book.title
+            entries = calibre_db.order_authors(book)
+            author_names = []
+            for authr in entries.authors:
+                author_names.append(authr.name.replace('|', ','))
+
+            title_change = handle_title_on_edit(book, " ".join(author_names))
+            input_authors, authorchange = handle_author_on_edit(book, authors)
+            if authorchange or title_change:
+                edited_books_id = book.id
+                modif_date = True
+
+            if config.config_use_google_drive:
+                gdriveutils.updateGdriveCalibreFromLocal()
+
+            if edited_books_id:
+                helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0])
+            if modif_date:
+                book.last_modified = datetime.utcnow()
+            try:
+                calibre_db.session.commit()
+            except (OperationalError, IntegrityError) as e:
+                calibre_db.session.rollback()
+                log.error("Database error: %s", e)
+                return json.dumps({'success': False})
+
+            if config.config_use_google_drive:
+                gdriveutils.updateGdriveCalibreFromLocal()
+        return json.dumps({'success': True})
+    return ""
diff --git a/cps/static/js/table.js b/cps/static/js/table.js
index 886948377a62e6b8c6d5e8171554b9588efec5ee..a38ca1c61fd1f2041d8a584ec4640dfd3eb7deb9 100644
--- a/cps/static/js/table.js
+++ b/cps/static/js/table.js
@@ -46,9 +46,14 @@ $(function() {
             if (selections.length < 1) {
                 $("#delete_selection").addClass("disabled");
                 $("#delete_selection").attr("aria-disabled", true);
+                $("#table_xchange").addClass("disabled");
+                $("#table_xchange").attr("aria-disabled", true);
             } else {
                 $("#delete_selection").removeClass("disabled");
                 $("#delete_selection").attr("aria-disabled", false);
+                $("#table_xchange").removeClass("disabled");
+                $("#table_xchange").attr("aria-disabled", false);
+
             }
         });
     $("#delete_selection").click(function() {
@@ -86,6 +91,20 @@ $(function() {
         });
     });
 
+    $("#table_xchange").click(function() {
+        $.ajax({
+            method:"post",
+            contentType: "application/json; charset=utf-8",
+            dataType: "json",
+            url: window.location.pathname + "/../../ajax/xchange",
+            data: JSON.stringify({"xchange":selections}),
+            success: function success() {
+                $("#books-table").bootstrapTable("refresh");
+                $("#books-table").bootstrapTable("uncheckAll");
+            }
+        });
+    });
+
     var column = [];
     $("#books-table > thead > tr > th").each(function() {
         var element = {};
diff --git a/cps/templates/book_table.html b/cps/templates/book_table.html
index d088e54b8e0aa4b621f26ea7d4b14a18047254aa..e340dc0a0090cabd3c779e5f0f1942d15ff262df 100644
--- a/cps/templates/book_table.html
+++ b/cps/templates/book_table.html
@@ -20,17 +20,20 @@
 {% block body %}
 <h2 class="{{page}}">{{_(title)}}</h2>
       <div class="col-xs-12 col-sm-6">
-        <div class="row">
+        <div class="row form-group">
           <div class="btn btn-default disabled" id="merge_books" data-toggle="modal" data-target="#mergeModal" aria-disabled="true">{{_('Merge selected books')}}</div>
           <div class="btn btn-default disabled" id="delete_selection" aria-disabled="true">{{_('Remove Selections')}}</div>
         </div>
+        <div class="row form-group">
+            <div class="btn btn-default disabled" id="table_xchange" ><span class="glyphicon glyphicon-arrow-up"></span><span class="glyphicon glyphicon-arrow-down"></span>{{_('Exchange author and title')}}</div>
+        </div>
       </div>
-     <div class="col-xs-12 col-sm-6">
-      <div class="row">
+     <div class="filterheader col-xs-12 col-sm-6">
+      <div class="row form-group">
         <input type="checkbox" id="autoupdate_titlesort" name="autoupdate_titlesort" checked>
         <label for="autoupdate_titlesort">{{_('Update Title Sort automatically')}}</label>
       </div>
-      <div class="row">
+      <div class="row form-group">
         <input type="checkbox" id="autoupdate_authorsort" name="autoupdate_authorsort" checked>
         <label for="autoupdate_authorsort">{{_('Update Author Sort automatically')}}</label>
       </div>