一旦顯式調用Close方法或將連接放入Using語句,是否需要關閉連接?離開連接是否會導致連接重用並提高SQL性能以用於將來的查詢?使用Dapper時的關閉連接
4
A
回答
11
我假設您使用的是最新版本的Dapper。
憑藉小巧玲瓏的,有管理的連接方式有兩種:
全面管理自己: 在這裏,你是打開和關閉連接承擔全部責任。這就像您在使用ADO.NET時對待連接的方式一樣。
允許小巧玲瓏來管理: 小巧玲瓏的自動打開的連接(如果它沒有打開),並關閉它(如果它是由小巧玲瓏開業)爲您服務。這與
DataAdapter.Fill()
方法類似。我個人不建議這樣。這可能不適用於每次。以下就是馬克Gravell說,在comment此答案之一:https://stackoverflow.com/a/12629170/5779732
很好,技術上打開/關閉是處置不同。如果你只打算打開/關閉個人電話,那麼你可以讓精巧的人來做。 如果您打開/關閉更廣的粒度(例如,每個請求),那麼對您的代碼執行此操作並將打開的連接傳遞給Dapper會更好。
當然,您可以在單個連接上調用多個查詢。但是,應該關閉連接(通過調用Close()
,Dispose()
方法或將其封裝在using
塊中)以避免資源泄漏。關閉連接將其返回到連接池。連接池的參與提高了新連接成本的性能。
除了只處理連接,我建議你實現UnitOfWork來管理事務。請參閱this GitHub上的優秀示例。
以下源代碼可能對您有所幫助。請注意,這是爲我的需要而編寫的;所以它可能不適合你。
public sealed class DalSession : IDisposable
{
public DalSession()
{
_connection = new OleDbConnection(DalCommon.ConnectionString);
_connection.Open();
_unitOfWork = new UnitOfWork(_connection);
}
IDbConnection _connection = null;
UnitOfWork _unitOfWork = null;
public UnitOfWork UnitOfWork
{
get { return _unitOfWork; }
}
public void Dispose()
{
_unitOfWork.Dispose();
_connection.Dispose();
}
}
public sealed class UnitOfWork : IUnitOfWork
{
internal UnitOfWork(IDbConnection connection)
{
_id = Guid.NewGuid();
_connection = connection;
}
IDbConnection _connection = null;
IDbTransaction _transaction = null;
Guid _id = Guid.Empty;
IDbConnection IUnitOfWork.Connection
{
get { return _connection; }
}
IDbTransaction IUnitOfWork.Transaction
{
get { return _transaction; }
}
Guid IUnitOfWork.Id
{
get { return _id; }
}
public void Begin()
{
_transaction = _connection.BeginTransaction();
}
public void Commit()
{
_transaction.Commit();
Dispose();
}
public void Rollback()
{
_transaction.Rollback();
Dispose();
}
public void Dispose()
{
if(_transaction != null)
_transaction.Dispose();
_transaction = null;
}
}
interface IUnitOfWork : IDisposable
{
Guid Id { get; }
IDbConnection Connection { get; }
IDbTransaction Transaction { get; }
void Begin();
void Commit();
void Rollback();
}
現在,您的存儲庫應該以某種方式接受此UnitOfWork。我用構造函數選擇依賴注入。
public sealed class MyRepository
{
public MyRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
IUnitOfWork unitOfWork = null;
//You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer.
public MyPoco Get()
{
return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......);
}
public void Insert(MyPoco poco)
{
return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........);
}
}
然後調用它像這樣:
隨着交易:
using(DalSession dalSession = new DalSession())
{
UnitOfWork unitOfWork = dalSession.UnitOfWork;
unitOfWork.Begin();
try
{
//Your database code here
MyRepository myRepository = new MyRepository(unitOfWork);
myRepository.Insert(myPoco);
//You may create other repositories in similar way in same scope of UoW.
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
沒有交易:
using(DalSession dalSession = new DalSession())
{
//Your database code here
MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called.
myRepository.Insert(myPoco);
}
這種方式,而不是直接暴露在你的呼叫連接代碼,你可以在一個位置控制它。
有關上述代碼中有關Repository的更多詳細信息,請參閱here。
請注意,UnitOfWork
是more而不僅僅是交易。儘管這個代碼只處理事務。您可以擴展此代碼以涵蓋其他角色。
相關問題
- 1. 使用LdapTemplate時LDAP連接未關閉
- 2. 使用Oracle UCP時連接關閉
- 3. 在使用連接池時關閉連接的位置?
- 4. c3p0連接池充分事件連接關閉時關閉
- 5. 超時:底層連接已關閉:連接意外關閉
- 6. mysql_pconnect()連接何時關閉
- 7. 何時關閉http連接
- 8. 關閉連接
- 9. 使用LINQ關閉與DB的連接?
- 10. 連接關閉時,ODP.net是否關閉了引用遊標?
- 11. 當應用程序關閉時,jdbctemplate關閉連接?
- 12. PHP:關閉套接字連接時,網頁關閉
- 13. 使用HTTP Servlets中的連接池關閉連接的位置
- 14. 「的基礎連接已關閉:連接被意外關閉」
- 15. 用扭曲關閉連接
- 16. ajax調用關閉連接
- 17. 使用「使用」語句時是否需要關閉連接
- 18. 何時關閉PHP中的連接?
- 19. MongoEngine:關閉連接
- 20. java.sql.SQLRecoverableException:關閉連接
- 21. 關閉oracle連接
- 22. SoapUI連接關閉
- 23. 關閉連接 - InputStream
- 24. 關閉SQLDataSource連接
- 25. Oracle連接關閉
- 26. 關閉SQLObject連接
- 27. nodejs。關閉連接
- 28. 連接未關閉
- 29. PDO關閉連接
- 30. PHP連接:關閉
我不能完全同意你對你的第二意見。有時讓精巧的管理連接是一個更好的選擇。我想引用來自https://stackoverflow.com/a/12629170/1262198: 的Marc Gravell「技術上的開放/關閉與處置不同,如果您只打算打開/關閉個別通話,您可能會如果你以更大的粒度打開/關閉(比如每個請求),最好讓你的代碼做到這一點,並將打開的連接傳遞給Dapper。「 – Arvand
@Arvand:同意。我糾正了我的答案。我只是說這可能不適用於每一次。 –