承前一节,我们使用相同的库,操作 PostgreSQL。
// 写法一 using (NpgsqlConnection conn = new NpgsqlConnection("Data Source=.; Initial Catalog=itpow; Integrated Security=SSPI;")) { using (TransactionScope ts = new TransactionScope()) { conn.Open(); try { Do1(conn); // 假设 Do1 中的 SQL 语句正常 Do2(conn); // 假设 Do2 中的 SQL 语句出错,抛出异常 } catch(Exception) { } ts.Complete(); conn.Close(); } } // 写法二、推荐 using (NpgsqlConnection conn = new NpgsqlConnection("Data Source=.; Initial Catalog=itpow; Integrated Security=SSPI;")) { using (TransactionScope ts = new TransactionScope()) { conn.Open(); try { Do1(conn); // 假设 Do1 中的 SQL 语句正常 Do2(conn); // 假设 Do2 中的 SQL 语句出错,抛出异常 ts.Complete(); } catch(Exception) { } conn.Close(); } }
如上,两种写法,主要区别在于 ts.Complete() 的位置。
在 SQL Server 中
写法一、由于 ts.Complete() 得到了执行,所以 Do1 中的 SQL 得到了提交,事务无效。(注:此处“有效”、“无效”是指与我们的业务期望,并非指“事务”是否工作。)
写法二、由于抛出异常,ts.Complete() 没有得到执行,所以 Do1 中的 SQL 没有被提交,事务有效。
在 PostgreSQL 中
写法一、虽然 ts.Complete() 得到了执行,但是识别到了中途有 SQL 错误,ts.Complete() 内部并没有执行,事务有效。
写法二、由于抛出异常,ts.Complete() 没有得到执行,所以 Do1 中的 SQL 没有被提交,事务有效。
从推荐的角度来说,写法二更好。