method for retrying database queries/transactions

It is best practice to implement retry logic for transactions that are aborted because of deadlocks or timeouts. This makes such method available inside the DBAL and also adds detection for errors where retrying makes sense in the different database drivers.

Deadlocks and timeouts are caused by lock contention and you often can design your application to reduce the likeliness that such an error occurs. But it's impossible to guarantee that such error conditions will never occur. This is why implementing retrying logic for such errors is actually a must when you have to ensure the application does not fail in edge cases or high load.
Some references where something similar has already been discussed and implemented:
- [SQL Server](http://www.mssqltips.com/sqlservertip/3188/implementing-sql-server-transaction-retry-logic-for-failed-transactions/)
- [Java Spring with Hibernate](http://java.dzone.com/articles/automatic-deadlock-retry)
- [Google App Engine](http://forum.spring.io/forum/spring-projects/data/72661-how-to-retry-a-failed-transaction)

I chose the name `retryable` because it is consistent with `transactional`. I think the implementation is quite straight forward and fits very well with the DBAL design.

In our case we had seldomly errors like 
- `Doctrine\\DBAL\\Exception\\DriverException: An exception occurred while executing 'UPDATE product SET modified = ? WHERE id = ?' with params [\"2014-10-15 16:28:55\", \"460315800000\"]:\n\nSQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction`
- `Doctrine\\DBAL\\Exception\\DriverException: An exception occurred while executing 'INSERT INTO ... VALUES (...)' with params [\"...\", \"...\"]:\n\nSQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction`

As you can see even the exception message suggests to retry the transaction. This is now easily possible with

```
$retryWrapper = new RetryWrapper(function () use ($con) {
    return $con->update('tablename', array('field' => 'data'), array('id' => 'myid'));
});

$affectedRows = $retryWrapper();
```
So what should I do? I can collect the exceptions and throw a new `RetryFailureException implements RetryableException` with the previous exceptions. But as stof said, this would mean a different exception is thrown afterwards.