应用程序层使SQL事务错误无效

时间:2014-04-05 14:16:00

标签: c# sql sql-server asp.net-mvc

我有一个存储过程

create proc spInsertRole
@rolename varchar(50)
as
begin
    set nocount on
    begin try
    begin tran
        if len(@roleName) > 15
            Raiserror('Role name is too long',1,5)
        insert into webpages_Roles(RoleName)
        values (@roleName)
        commit tran
        end try
    begin catch
        select ERROR_MESSAGE() as ErrorMessage
    rollback tran
    end catch
end

如果我在SSMS中并且尝试添加超过15个字符的角色,则此代码将阻止这种情况发生并给我一条错误消息Role name is too long

当我使用以下C#时,此代码将允许将记录添加到数据库中。我需要知道为什么C#SqlTransaction取代SQL Server,我在哪里将roleName.Length > 15检查到C#代码中,向用户显示角色名称太长的错误(这是一个MVC应用程序)。

public void InsertRole(string roleName)
        {
            using (var con = new SqlConnection(cs))
            {
                con.Open();
                SqlTransaction transaction;
                transaction = con.BeginTransaction();
                SqlCommand command = new SqlCommand("spInsertRole", con, transaction);
                try
                {
                    command.CommandType = CommandType.StoredProcedure;
                    command.Parameters.AddWithValue("@roleName", roleName);
                    command.ExecuteNonQuery();
                    transaction.Commit();
                }
                //how to throw this to the UI in MVC?
                catch (Exception ex)
                {
                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception rollBackException)
                    {

                        throw;
                    }
                }


            }
        }

1 个答案:

答案 0 :(得分:0)

您使用严重性为1的RAISERROR,但严重性为10或更低并且不会将控制权转移到CATCH块,它只会打印错误消息。使用更高的严重性。

比较此代码snipet:

declare @rolename varchar(50) = '123456789123456789'
begin try
    begin tran
    if len(@roleName) > 15
        Raiserror('Role name is too long',1,5)
    print 'inserting...'
    insert into webpages_Roles(RoleName)
    values (@roleName)
    print 'committing...'
    commit tran
end try
begin catch
    print 'catch'
    select ERROR_MESSAGE() as ErrorMessage
    print 'rolling back...'
    rollback tran
end catch

有了这个:

declare @rolename varchar(50) = '123456789123456789'
begin try
    begin tran
    if len(@roleName) > 15
        Raiserror('Role name is too long',11,5)
    print 'inserting...'
    insert into webpages_Roles(RoleName)
    values (@roleName)
    print 'committing...'
    commit tran
end try
begin catch
    print 'catch'
    select ERROR_MESSAGE() as ErrorMessage
    print 'rolling back...'
    rollback tran
end catch

第一个使用严重性1,控制不转移到CATCH块;另一个使用严重性11,并最终在CATCH中。