@optional_arg_decorator
def error_rollback(func, arg_name='on_error', implicit=False):

    @wraps(func)
    def wrapped_func(*args, **kwargs):
        with Rollback() as manager:
            if implicit:
                fglobals = func.__globals__
                has_arg = (arg_name in fglobals)
                old_val = fglobals.get(arg_name)
                fglobals[arg_name] = manager
                try:
                    func(*args, **kwargs)
                finally:
                    if has_arg:
                        func.__globals__[arg_name] = old_val
                    else:
                        func.__globals__.pop(arg_name)
            else:
                kwargs[arg_name] = manager
                func(*args, **kwargs)
    return wrapped_func
@optional_arg_decorator
def error_rollback(func, arg_name='on_error', implicit=False):

    @wraps(func)
    def wrapped_func(*args, **kwargs):
        with Rollback() as manager:
            if implicit:
                fglobals = func.__globals__
                has_arg = (arg_name in fglobals)
                old_val = fglobals.get(arg_name)
                fglobals[arg_name] = manager
                try:
                    func(*args, **kwargs)
                finally:
                    if has_arg:
                        func.__globals__[arg_name] = old_val
                    else:
                        func.__globals__.pop(arg_name)
            else:
                kwargs[arg_name] = manager
                func(*args, **kwargs)
    return wrapped_func