通常数据库事务处理代码都采用如下的模式编写:
打开数据库连接();
try
{
开启事务();
数据库操作1();
数据库操作2();
......;
数据库操作n();
提交事务();
}
catch (Exception err)
{
回滚事务();
throw err; // 重新抛出异常(导致异常的堆栈信息发生变化,无法知道原始异常所在位置,不利于调试)
}
finally
{
关闭数据库连接();
}
在使用中经常因为 SQL 语句或某个未知的错误导致异常和事务失败,但在 catch 块中由于 trhow err 被重新抛出,异常的堆栈信息发生变化,无法知道原始异常所在位置。所以应该避免在 catch 简单地重抛异常,改进方式比较多:
方式1)改进catch块代码,如下:
...
catch (Exception err)
{
回滚事务();
throw new Exception(err.Message, err); // 重新抛出异常,内部异常信息不会丢失
}
...
用 AppFramework 来编写的例程如下:
IDBSession ss = DBSessionManager.Default.GetSession();
try
{
ss.BeginTran();
...
ss.CommitTran();
}
catch (Exception err)
{
ss.RollbackTran();
throw new Exception(err.Message, err);
}
finally
{
ss.Close();
}
方式2)如果不需要异常处理,干脆去掉 catch 块,让事务在连接关闭时自动回滚
打开数据库连接();
try
{
开启事务();
数据库操作1();
数据库操作2();
......;
数据库操作n();
提交事务();
}
finally
{
关闭数据库连接(); // 关闭连接,并自动回滚未提交的事务
}
用 AppFramework 来编写的例程如下,非常简洁:
using (IDBSession ss = DBSessionManager.Default.GetSession())
{
ss.BeginTran();
...
ss.CommitTran();
}