網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、概述
1、事務(wù)ACID特性
事務(wù)將一系列的工作視為一個(gè)工作單元,它具有 ACID 特性:
-
A:Atomicity 不可分性?
也就是說(shuō)事務(wù)中有多項(xiàng)工作,如果有一項(xiàng)工作失敗了,整個(gè)事務(wù)就算失敗了。 -
C:Consistency 一致性?
事務(wù)完成時(shí),全部數(shù)據(jù)必須維持一致性的狀態(tài)。對(duì)于關(guān)系數(shù)據(jù)庫(kù),簡(jiǎn)單地來(lái)說(shuō)就是沒(méi)有破壞數(shù)據(jù)完整性。 -
I:Isolation 隔離性?
事務(wù)與其他事務(wù)是隔離的,也就是說(shuō)一個(gè)事務(wù)的一項(xiàng)工作對(duì)數(shù)據(jù)進(jìn)行修改時(shí),如果整個(gè)事務(wù)還沒(méi)有結(jié)束,其他事務(wù)就無(wú)法知道這個(gè)數(shù)據(jù)發(fā)生了修改。 -
D:Durability 持久性?
事務(wù)完成后,其作用便永遠(yuǎn)存在于系統(tǒng)之中。
2、.NET開發(fā)者用到的5種事務(wù)機(jī)制:
- SQL和存儲(chǔ)過(guò)程級(jí)別的事務(wù)。(數(shù)據(jù)庫(kù)事務(wù))
- ADO.NET級(jí)別的事務(wù)。
- ASP.NET頁(yè)面級(jí)別的事務(wù)。
- 企業(yè)級(jí)服務(wù)COM+事務(wù)。
- System.Transactions 事務(wù)處理。
這5種事務(wù)機(jī)制有著各自的優(yōu)勢(shì)和劣勢(shì),分別表現(xiàn)在性能、代碼數(shù)量和部署設(shè)置等方面。開發(fā)人員可以根據(jù)項(xiàng)目的實(shí)際情況選擇相應(yīng)的事務(wù)機(jī)制。
二、數(shù)據(jù)庫(kù)事務(wù)
1、不同數(shù)據(jù)庫(kù)的事務(wù)規(guī)則
數(shù)據(jù)庫(kù)事務(wù)是其他事務(wù)模型的基礎(chǔ),當(dāng)一個(gè)事務(wù)創(chuàng)建時(shí)不同數(shù)據(jù)庫(kù)系統(tǒng)都有自己的規(guī)則。
- SQL Server默認(rèn)在自動(dòng)提交的模式下工作,每個(gè)語(yǔ)句執(zhí)行完后都會(huì)立即提交;
- Oracle則需要你包含一個(gè)提交語(yǔ)句。
- 當(dāng)一個(gè)語(yǔ)句通過(guò)OLE DB執(zhí)行時(shí),它執(zhí)行完后一個(gè)提交動(dòng)作會(huì)被附加上去。
例如:SQL Server數(shù)據(jù)庫(kù)T-SQL語(yǔ)句中顯示指定事務(wù)
declare @TranName varchar(20);
select @TranName = 'MyTransaction';
begin transaction @TranName;
go
use AdventureWorks;
go
delete from AdventureWorks.HumanResources.JobCandidate where JobCandidateID = 13;
go
commit transaction MyTransaction;
go
或在存儲(chǔ)過(guò)程中使用
create procedure Tran1
as
begin tran;
set xact_abort on; --set xact_abort on表示遇到錯(cuò)誤立即回滾。
insert into P_Category ( CategoryId, Name ) values ( '1', 'test1' );
insert into P_Category ( CategoryId, Name ) values ( '2', 'test2' );
commit tran;
go
2、數(shù)據(jù)庫(kù)事務(wù)的優(yōu)勢(shì)和限制
(1)優(yōu)勢(shì):
- 所有的事務(wù)邏輯包含在一個(gè)單獨(dú)的調(diào)用中。
- 擁有運(yùn)行一個(gè)事務(wù)的最佳性能。
- 獨(dú)立于應(yīng)用程序。
(2)限制:
- 事務(wù)上下文僅存在于數(shù)據(jù)庫(kù)調(diào)用中。
- 數(shù)據(jù)庫(kù)代碼與數(shù)據(jù)庫(kù)系統(tǒng)有關(guān)。
三、ADO.Net事務(wù)
ADO.Net事務(wù)為System.Data.Common.DbTransaction類的各種派生類。ADO.Net事務(wù)不是分布式事務(wù),不支持跨多個(gè)連接,它總是關(guān)聯(lián)到一個(gè)連接上的本地事務(wù)上。
ADO.NET 顯式事務(wù)占用資源少、速度快,但功能簡(jiǎn)單,只能管理單一對(duì)象和單一持久資源間的事務(wù)。
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString))
{
conn.Open();
using (SqlTransaction tran = conn.BeginTransaction())
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.Transaction = tran;
cmd.CommandType = CommandType.Text;
try
{
cmd.CommandText = "insert into TranTable(Priority) values(1)";
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into TranTable(Priority) values(256)";
cmd.ExecuteNonQuery();
tran.Commit();
Response.Write("Ok");
}
catch (SqlException ex)
{
tran.Rollback();
Response.Write("Error:" + ex.Message);
}
}
}
conn.Close();
}
四、System.EnterpriseServices自動(dòng)事務(wù)處理
不需要顯示進(jìn)行事務(wù)處理,運(yùn)行庫(kù)自動(dòng)創(chuàng)建事務(wù)。多個(gè)對(duì)象能輕松的運(yùn)行在同一個(gè)事務(wù)中。但它需要COM+主機(jī)模型。
使用此技術(shù)的類必須派生自ServicedComponen類。
[Transaction(TransactionOption.Required)]
public class OrderContrl : ServicedComponent
{
[AutoComplete]
public void NewOrder(Order order)
{
using (OrderData data = new OrderData())
{
data.Insert(order);
}
}
}
五、System.Transactions事務(wù)
System.Transactions是所有事務(wù)處理類的基類。
System.Transactions基礎(chǔ)結(jié)構(gòu)通過(guò)支持SQL Server、ADO.NET、MSMQ和Microsoft分布式事務(wù)協(xié)調(diào)器(MSDTC)中啟動(dòng)的事務(wù),使得整個(gè)平臺(tái)的事務(wù)編程變得簡(jiǎn)單和高效。
它既提供了基于Transaction 類的顯式編程模型,也提供了使用TransactionScope類的隱式編程模型,它里面的事務(wù)由基礎(chǔ)設(shè)施自動(dòng)管理。強(qiáng)烈建議使用更簡(jiǎn)單的隱式開發(fā)模型TransactionScope。
1、顯式事務(wù)(Explicit Transaction)
提交、回滾事務(wù)都由程序員編程來(lái)決定的方式,叫“顯式事務(wù)(Explicit Transaction)”。Transaction 類及其派生類為顯式事務(wù)。
2、Transaction類的派生類
- CommittableTransaction:可提交的事務(wù)
- DependentTransaction:依賴事務(wù)
- SubordinateTransaction:可以委托的下屬事務(wù)
3、Transaction類成員
- Current:獲取或設(shè)置環(huán)境事務(wù)。
- IsolationLevel:獲取事務(wù)的隔離級(jí)別。
- TransactionInformation:檢索有關(guān)某個(gè)事務(wù)的附加信息。
- DependentClone(DependentCloneOption) :創(chuàng)建事務(wù)的依賴復(fù)本。
- Rollback() :回滾(中止)事務(wù)。
- Dispose():釋放由該對(duì)象占用的資源。
- TransactionCompleted:指示事務(wù)已完成。
六、可提交的事務(wù):CommitableTransaction(顯式事務(wù))
唯一支持提交的事務(wù)類是CommitableTransaction,它直接繼承自Transaction。
CommittableTransaction提供了“Commit”同步方法和“BeginCommit”、“EndCommit”異步方法組合對(duì)事務(wù)的提交。
創(chuàng)建CommittableTransaction事務(wù)并不會(huì)自動(dòng)設(shè)置環(huán)境事務(wù)。
CommittableTransaction事務(wù)不能被重用。可以將數(shù)據(jù)庫(kù)連接登記到事務(wù)。
注意:只有一個(gè)DbConnection時(shí)為本地事務(wù);當(dāng)存在多個(gè)DbConnection時(shí)才會(huì)啟動(dòng)MSDTC(MSDTC不夠穩(wěn)定,盡量避免引入分布式服務(wù))
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString))
{
using (CommittableTransaction ct = new CommittableTransaction ())
{
conn.Open();
conn.EnlistTransaction(ct);//將數(shù)據(jù)庫(kù)連接登記到事務(wù)
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
try
{
cmd.CommandText = "insert into TranTable(Priority) values(1)";
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into TranTable(Priority) values(256)";
cmd.ExecuteNonQuery();
ct.Commit(); //提交事務(wù)
Response.Write("Ok");
}
catch (SqlException ex)
{
ct.Rollback();//回滾事務(wù)
Response.Write("Error:" + ex.Message);
}
}
conn.Close();
}
}
七、環(huán)境事務(wù):TrasactionScope(隱式事務(wù),推薦)
TransactionScope為隱式事務(wù)。它為一組事務(wù)型操作創(chuàng)建一個(gè)執(zhí)行范圍,而這個(gè)范圍始于TransactionScope創(chuàng)建之時(shí),結(jié)束于TransactionScope被回收(調(diào)用Dispose方法)。
TransactionScope實(shí)現(xiàn)了IDisposable接口,除了Dispose方法之外,僅僅具有一個(gè)唯一的方法:Complete()。
目前 TransactionScope 只能處理數(shù)據(jù)庫(kù)的事務(wù),對(duì)于其他事務(wù),如 I/O,目前的 .NET 版本無(wú)法處理。
using (SqlConnection conn = new SqlConnection("Data Source=.; Initial Catalog=TestDb; Integrated Security=SSPI;"))
{
using (TransactionScope ts = new TransactionScope())
{
conn.Open();
try
{
SqlCommand cmd = new SqlCommand(conn);
cmd.CommandText = "INSERT INTO [Test]([Name],[Value]) VALUES ('測(cè)試1','1')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [Test]([Name],[Value]) VALUES ('測(cè)試2','2')";
cmd.ExecuteNonQuery();
ts.Complete();
}
catch (SqlException)
{
}
conn.Close();
}
}
TransactionScope卻有一組豐富的構(gòu)造函數(shù)。我們先來(lái)看看這些構(gòu)造函數(shù)相應(yīng)的參數(shù)如何影響TransactionScope對(duì)事務(wù)控制的行為。
void Main()
{
TransactionOptions transactionOptions = new TransactionOptions()
{
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
Timeout = new TimeSpan(0, 2, 0)//超時(shí)間隔兩分鐘
};
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
Transaction.Current.TransactionCompleted += (sender, args) =>
{
Console.Write(args.Transaction.TransactionInformation.LocalIdentifier);
}
AddStudent(new Student { });
scope.Complete();//提交事務(wù)
}
}
public void AddStudent(Student s)
{
SqlConnection conn = new SqlConnection();//環(huán)境事務(wù)內(nèi)新建的連接自動(dòng)附加到事務(wù)
//如果連接在TransactionScope建立之前已存在,需要手工用conn.EnlistTrasaction(Transaction.Current)登記事務(wù)
conn.Open();
try
{
SqlCommand command = new SqlCommand();
}
catch (Exception ex)
{
throw;
}
}
1、隔離級(jí)別IsolationLevel
7個(gè)隔離級(jí)別之中,Serializable具有最高隔離級(jí)別,代表的是一種完全基于序列化(同步)的數(shù)據(jù)存取方式。按照隔離級(jí)別至高向低,7個(gè)不同的隔離級(jí)別代表的含義如下:
- Serializable:可序列化。(默認(rèn),最高級(jí)別)可以在事務(wù)期間讀取可變數(shù)據(jù),但是不可以修改,也不可以添加任何新數(shù)據(jù);
- RepeatableRead:可重復(fù)讀。可以在事務(wù)期間讀取可變數(shù)據(jù),但是不可以修改。可以在事務(wù)期間添加新數(shù)據(jù);
- ReadCommitted:可讀已提交的數(shù)據(jù)。不可以在事務(wù)期間讀取可變數(shù)據(jù),但是可以修改它;
- ReadUncommitted:讀未提交的數(shù)據(jù)。可以在事務(wù)期間讀取和修改可變數(shù)據(jù);
- Snapshot:快照。可以讀取可變數(shù)據(jù)。在事務(wù)修改數(shù)據(jù)之前,它驗(yàn)證在它最初讀取數(shù)據(jù)之后另一個(gè)事務(wù)是否更改過(guò)這些數(shù)據(jù)。如果數(shù)據(jù)已被更新,則會(huì)引發(fā)錯(cuò)誤。這樣使事務(wù)可獲取先前提交的數(shù)據(jù)值;
- Chaos:混亂。無(wú)法覆蓋隔離級(jí)別更高的事務(wù)中的掛起的更改;
- Unspecified:未指定。正在使用與指定隔離級(jí)別不同的隔離級(jí)別,但是無(wú)法確定該級(jí)別。如果設(shè)置了此值,則會(huì)引發(fā)異常。
2、嵌套環(huán)境事務(wù)
using (TransactionScope outerScope = new TransactionScope())
{
using (TransactionScope innerScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
//事務(wù)型操作
innerScope.Complete();
}
//事務(wù)型操作
outerScope.Complete();
}
3、TransactionScopeOption
使用TransactionScopeOptions可以改變TransactionScope的默認(rèn)事務(wù)類型。
- Required:(默認(rèn))如果已經(jīng)存在一個(gè)事務(wù),那么這個(gè)事務(wù)范圍將加入已有的事務(wù)。否則,它將創(chuàng)建自己的事務(wù)。
- RequiresNew:這個(gè)事務(wù)范圍將創(chuàng)建自己的事務(wù)。
- Suppress:抑制。 將事務(wù)范圍內(nèi)的環(huán)境事務(wù)設(shè)為空,意味著事務(wù)范圍內(nèi)的操作并不受事務(wù)的控制。當(dāng)部分代碼需要留在事務(wù)外部時(shí),可以使用該選項(xiàng)。
4、MSDTC組件設(shè)置:
一般情況下只要你使用"TransactionScope",都要配置MSDTC,要配防火墻,要開139端口,這個(gè)端口不可以更改。
- 如果WEB服務(wù)器和數(shù)據(jù)庫(kù)是在同一臺(tái)服務(wù)器上,TransactionScope使用的是本地事務(wù),這時(shí)不需要配置MSDTC。
- 如果WEB服務(wù)器和數(shù)據(jù)庫(kù)不在同一臺(tái)服務(wù)器上,TransactionScope會(huì)自動(dòng)提升事務(wù)級(jí)別為分布式事務(wù),這時(shí)就需要配置MSDTC。
對(duì)MSDTC組件設(shè)置:控制面板--->管理工具--->服務(wù) 中,開啟Distributed Transaction Coordinator 服務(wù)。
- 控制面板->管理工具->組件服務(wù)->計(jì)算機(jī)->我的電腦->右鍵->屬性,選擇MSDTC頁(yè), 確認(rèn)"使用本地協(xié)調(diào)器"。
- 點(diǎn)擊下方"安全配置"按鈕
- 勾選: "允許網(wǎng)絡(luò)DTC訪問(wèn)","允許遠(yuǎn)程客戶端","允許入站","允許出站","不要求進(jìn)行身份驗(yàn)證".
- 對(duì)于數(shù)據(jù)庫(kù)服務(wù)器端, 可選擇"要求對(duì)呼叫方驗(yàn)證"
- 勾選:"啟用事務(wù)Internet協(xié)議(TIP)事務(wù)"。
- 在雙方防火墻中增加MSDTC.exe例外?
可用命令行: netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable
八、依賴事務(wù)DependentTransaction,跨多個(gè)線程調(diào)用事務(wù)(顯式事務(wù))
一個(gè)環(huán)境事務(wù)綁定到一個(gè)線程上,如果新建了一個(gè)線程它就不會(huì)有第一個(gè)線程中的環(huán)境事務(wù),兩個(gè)線程中的事務(wù)完全獨(dú)立。
如果多個(gè)線程使用同一個(gè)環(huán)境事務(wù),需要給新線程傳遞一個(gè)依賴事務(wù),調(diào)用Transaction的DependentClone方法創(chuàng)建依賴事務(wù)。
依賴事務(wù)通過(guò)DependentTransaction類型表示,和CommittableTransaction一樣,DependentTransaction也是Transaction的子類。
DependentTransaction依賴于現(xiàn)有的Transaction對(duì)象而存在,相當(dāng)于被依賴事務(wù)的子事務(wù),具有一個(gè)唯一的方法成員:Complete。調(diào)用這個(gè)方法意味著向被依賴事務(wù)發(fā)送通知,表明所有與依賴事務(wù)相關(guān)的操作已經(jīng)完成。
DependentClone方法具有一個(gè)DependentCloneOption枚舉類型的參數(shù):
- BlockCommitUntilComplete:表示被依賴事務(wù)在提交前會(huì)一直等待接收到依賴事務(wù)(子事務(wù))的通知(調(diào)用Complete或者Rollback方法)或者超過(guò)事務(wù)設(shè)定的超時(shí)時(shí)限;
- RollbackIfNotComplete:如果被依賴事務(wù)在依賴事務(wù)(子事務(wù))之前先完成,直接將被依賴的事務(wù)回滾,并拋出TransactionAbortedException異常。
下面的代碼示例演示如何創(chuàng)建一個(gè)依賴事務(wù)來(lái)管理兩個(gè)并發(fā)任務(wù),具體為克隆一個(gè)依賴的事務(wù)并將其傳遞給輔助線程。
void Main()
{
using (TransactionScope scope = new TransactionScope())
{
DependentTransaction dTx = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
Thread thread = new Thread(ThreadMethod);
thread.Start(dTx);
/* Do some transactional work here, then: */
scope.Complete();
}
}
public void ThreadMethod(object transaction)
{
DependentTransaction dTx = transaction as DependentTransaction;
try
{
//將DependentTransaction對(duì)象作為TransactionScope的參數(shù),以初始化環(huán)境事務(wù)
using (TransactionScope ts = new TransactionScope(dTx))
{
/* Perform transactional work here */
ts.Complete();//完成環(huán)境事務(wù)
}
}
finally
{
dTx.Complete();//完成依賴事務(wù)
dTx.Dispose();
}
}
原文鏈接:https://www.cnblogs.com/springsnow/p/9391862.html
相關(guān)推薦
- 2022-11-04 使用EF?Code?First搭建簡(jiǎn)易ASP.NET?MVC網(wǎng)站并允許數(shù)據(jù)庫(kù)遷移_實(shí)用技巧
- 2022-09-09 Oracle存儲(chǔ)過(guò)程與函數(shù)的詳細(xì)使用教程_oracle
- 2022-09-19 python正則表達(dá)式re.sub各個(gè)參數(shù)的超詳細(xì)講解_python
- 2022-08-30 C#中的委托和事件詳解_C#教程
- 2023-04-18 Android?懸浮按鈕之實(shí)現(xiàn)兔兔按鈕示例_Android
- 2022-05-28 pycharm安裝深度學(xué)習(xí)pytorch的d2l包失敗問(wèn)題解決_python
- 2022-08-06 C語(yǔ)言詳解關(guān)鍵字sizeof與unsigned及signed的用法_C 語(yǔ)言
- 2023-01-10 阿里云服務(wù)器?jdk1.8?安裝配置教程_服務(wù)器其它
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支