From 4d525a6f7569d1c90811f6d5e326321fb6f25015 Mon Sep 17 00:00:00 2001 From: Erol Fornoles Date: Sat, 21 May 2016 19:25:01 +0800 Subject: Add AR::TransactionSerializationError for transaction serialization failures or deadlocks --- .../connection_adapters/abstract_mysql_adapter.rb | 14 +++++++++++--- .../connection_adapters/postgresql_adapter.rb | 3 +++ activerecord/lib/active_record/errors.rb | 10 ++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 0f565277e3..44b4b547f3 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -727,14 +727,22 @@ module ActiveRecord column_names.map {|name| quote_column_name(name) + option_strings[name]} end + # See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html + ER_DUP_ENTRY = 1062 + ER_NO_REFERENCED_ROW_2 = 1452 + ER_DATA_TOO_LONG = 1406 + ER_LOCK_DEADLOCK = 1213 + def translate_exception(exception, message) case error_number(exception) - when 1062 + when ER_DUP_ENTRY RecordNotUnique.new(message) - when 1452 + when ER_NO_REFERENCED_ROW_2 InvalidForeignKey.new(message) - when 1406 + when ER_DATA_TOO_LONG ValueTooLong.new(message) + when ER_LOCK_DEADLOCK + TransactionSerializationError.new(message) else super end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index bab80a8890..ddfc560747 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -406,6 +406,7 @@ module ActiveRecord VALUE_LIMIT_VIOLATION = "22001" FOREIGN_KEY_VIOLATION = "23503" UNIQUE_VIOLATION = "23505" + SERIALIZATION_FAILURE = "40001" def translate_exception(exception, message) return exception unless exception.respond_to?(:result) @@ -417,6 +418,8 @@ module ActiveRecord InvalidForeignKey.new(message) when VALUE_LIMIT_VIOLATION ValueTooLong.new(message) + when SERIALIZATION_FAILURE + TransactionSerializationError.new(message) else super end diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index b8b8684cff..38e4fbec8b 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -285,6 +285,16 @@ module ActiveRecord class TransactionIsolationError < ActiveRecordError end + # TransactionSerializationError will be raised when a transaction is rolled + # back by the database due to a serialization failure or a deadlock. + # + # See the following: + # + # * http://www.postgresql.org/docs/current/static/transaction-iso.html + # * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock + class TransactionSerializationError < ActiveRecordError + end + # IrreversibleOrderError is raised when a relation's order is too complex for # +reverse_order+ to automatically reverse. class IrreversibleOrderError < ActiveRecordError -- cgit v1.2.3